home *** CD-ROM | disk | FTP | other *** search
/ Aminet 25 / Aminet 25 (1998)(GTI - Schatztruhe)[!][Jun 1998].iso / Aminet / dev / misc / FD2Pragma.lha / Source / FD2Pragma.c
Encoding:
C/C++ Source or Header  |  1998-04-29  |  109.6 KB  |  4,402 lines

  1. #define NAME     "FD2Pragma"
  2. #define VERSION  "2"
  3. #define REVISION "68"
  4. //#define DEBUG
  5. //#define DEBUG_OLD
  6.  
  7. /* Programmheader
  8.  
  9.     Name:        FD2Pragma
  10.     Author:     SDI
  11.     Distribution:    PD
  12.     Description:    creates pragmas files, lvo files and stub functions
  13.     Compileropts:    -
  14.     Linkeropts:    -gd
  15.  
  16.  1.2    : added pragmas for the Dice compiler. Available via switch "Dice".
  17.     added switches "Aztec", "SAS" and "Maxon": Maxon and Aztec just
  18.     turn on the default (except that Maxon expects pragma files to be
  19.     called "xxx_pragmas.h" instead of "xxx_lib.h"), SAS is equal to
  20.     Dice, except that SAS supports the pragma tagcall.
  21.  2.0    : Added support for tag functions. See the docs for details.
  22.     Author until this version:
  23.     Jochen Wiedmann
  24.     Am Eisteich 9
  25.     72555 Metzingen (Germany)
  26.     Tel. 07123 / 14881
  27.  2.1   19.08.96 : now made by SDI, added correct __MAXON__ support and
  28.     support for StormC++, added auto recognition of tagcall functions
  29.     changed the CLI interface completely
  30.  2.2   21.08.96 : fixed a lot of errors, added debug code
  31.  2.3   22.08.96 : little changes
  32.  2.4   24.08.96 : added proto-file creation
  33.  2.5   25.08.96 : added syscall and fix for functions ending in ...DMA
  34.  2.6   26.08.96 : fixed some errors, added CLIB parameter (used later for
  35.     CSTUBS)
  36.  2.7   01.09.96 : added correct Storm definition, added CLIB scan
  37.  2.8   02.09.96 : added assembler stub functions, added first ASM-stub code
  38.  2.9   04.09.96 : added Comment-Support
  39.  2.10  05.09.96 : changed CSTUB creation a bit
  40.  2.11  07.09.96 : speeded up output, reduced number of strndup calls
  41.  2.12  26.09.96 : pressing CTRL-C in early startup brought a wrong error
  42.     message - fixed
  43.  2.13  30.09.96 : made RegNames field to RegNames string - shorter Exe-file
  44.  2.14  01.10.96 : made SPECIAL 6 default, COMMENT also in LVO files
  45.  2.15  13.10.96 : corrected an error text
  46.  2.16  14.10.96 : added correct comment support and PRIVATE option
  47.  2.17  19.10.96 : now Maxon-compiled in Small data mode
  48.  2.18  22.10.96 : removed EXTERNC in Storm, Maxon and all pragmas, corrected
  49.     the texts, again SAS compiled
  50.  2.19  26.10.96 : added option to create FD files out of pragma files,
  51.     reworked a lot in the source
  52.  2.20  27.10.96 : fixed errors of previous version
  53.  2.21  28.10.96 : fixed error in CLIB scan
  54.  2.22  27.11.96 : SPECIAL numbers for lib and ASM code were wrong, removed
  55.     bug in Tag function stubs
  56.  2.23  06.12.96 : lib and stub creation still was wrong
  57.  2.24  31.12.96 : formed stub libs matching C++ file names, corrected CLIB
  58.     scan errors
  59.  2.25  04.01.97 : added HEADER option (I was asked for)
  60.  2.26  05.01.97 : added HEADER scan (in old file) and auto inserting
  61.  2.27  10.01.97 : stub functions missed register saving, outfuncs skip now,
  62.     when error occured (makes lots of error checking obsolete)
  63.  2.28  11.01.97 : forgot to add offset made by register saving
  64.  2.29  18.01.97 : now libtags and amitags defines only, when at least 1
  65.     tagfunc
  66.  2.30  13.02.97 : added local library base functions, rearranged SPECIAL
  67.           options, fixed some bugs
  68.  2.31  15.02.97 : corrected bugs inserted in previous version
  69.  2.32  16.02.97 : and again bug fixes, still didn't work
  70.  2.33  18.02.97 : corrected texts, added SPECIAL 28
  71.  2.34  25.03.97 : corrected Pragma --> FD file conversion, added ##shadow
  72.  2.35  26.03.97 : added STORMFD option, COMMENT, PRIVATE work again
  73.  2.36  29.03.97 : corrected *tagcall scan a bit
  74.  2.37  20.06.97 : added PASCAL stub lib production (SPECIAL 14, 15)
  75.  2.38  01.07.97 : fixed ##end handling
  76.  2.39  20.07.97 : added better proto file (__GNUC__ inline and pragma call),
  77.     removed C++ comments
  78.  2.40  24.11.97 : added new basenames to the list (devices and resources),
  79.     added tag-exception name checking (dos, utility libraries)
  80.  2.41  27.11.97 : fixed little bug with private functions, CSTUBS now
  81.     special option and no longer commandline arg, SPECIAL 10-15 got
  82.     numbers 11-16 (Sorry)
  83.  2.42  28.11.97 : Added two new warnings for CLIB
  84.  2.43  12.12.97 : faster FD file scan, one new warning
  85.  2.44  19.12.97 : fixed MODE settings for SPECIAL 15,16
  86.  2.45  30.01.98 : added function recognition, included inline creation,
  87.      inline stuff is based on fd2inline 1.11 (incomplete)
  88.  2.46  31.01.98 : continued inline stuff, fixed clib functions
  89.  2.47  05.02.98 : completed inline stuff, added alias names for dos functions
  90.  2.48  06.02.98 : changed Func interface - flags instead of tagmode
  91.  2.49  10.02.98 : fixed inline generation a bit, added SORTED argument,
  92.      RegNames got strings again
  93.  2.50  11.02.98 : bug-fixes, still did not work completely, hopefully got
  94.     all now
  95.  2.51  12.02.98 : and bug-fixes again :-(
  96.  2.52  15.02.98 : changed sorting order of arguments
  97.  2.53  20.02.98 : some code style changes
  98.  2.54  25.02.98 : added SMALLDATA model, removed 5 global variables (better
  99.     style), stub libs use MOVEM when possible, own MemRemember function
  100.  2.55  26.02.98 : bug fixes
  101.  2.56  15.03.98 : added FPU support
  102.  2.57  17.03.98 : added NOFPU keyword
  103.  2.58  19.03.98 : little fixes
  104.  2.59  20.03.98 : added enum and external type definitions defines
  105.  2.60  22.03.98 : added external types file scan
  106.  2.61  23.03.98 : fixed SAS flibcall, added FPU stubs
  107.  2.62  28.03.98 : bug fix with NOFPU and new option FPUONLY, total new clib
  108.     handling
  109.  2.63  29.03.98 : really lots of bug fixes, There are so much problems.
  110.     A better definition format would have been wonderful.
  111.  2.64  05.04.98 : bug fixes
  112.  2.65  07.04.98 : fixed Enforcer hit
  113.  2.66  08.04.98 : bug fix with type detection
  114.  2.67  20.04.98 : added GNU-only stuff
  115.  2.68  28.04.98 : SPECIAL 8 defaults to SAS-C names now
  116. */
  117.  
  118. #include <proto/exec.h>
  119. #include <proto/dos.h>
  120.  
  121. #include <exec/memory.h>
  122. #include <dos/doshunks.h>
  123.  
  124. #define SDI_TO_ANSI
  125. #include "SDI_ASM_STD_protos.h"
  126. #include "SDI_defines.h"
  127.  
  128. #ifdef __MAXON__        /* needed for -gd option */
  129.   #include <linkerfunc.h>
  130. #endif
  131.  
  132. #define TEXT_SAS    "__SASC"    /* verified    */
  133. #define TEXT_SAS_60    "__SASC_60"    /* verified    */
  134. #define TEXT_MAXON    "__MAXON__"    /* verified    */
  135. #define TEXT_STORM    "__STORM__"    /* verified    */
  136. #define TEXT_DICE    "_DCC"        /* in 2.0 code    */
  137. #define TEXT_AZTEC    "AZTEC_C"    /* verified    */
  138. #define TEXT_GNUC    "__GNUC__"    /* verified    */
  139.  
  140. #define FLAG_EXTERNC    (1<< 0)
  141. #define FLAG_SYSCALL    (1<< 1)
  142. #define FLAG_DOCOMMENT    (1<< 2)
  143. #define FLAG_PRIVATE    (1<< 3)
  144. #define FLAG_LOCALREG    (1<< 4)
  145. #define FLAG_STORMFD    (1<< 5)
  146. #define FLAG_PASCAL    (1<< 6)
  147. #define FLAG_SMALLDATA    (1<< 7)
  148. #define FLAG_DONE    (1<< 8) /* destination file is not empty */
  149. #define FLAG_INLINENEW    (1<< 9)
  150. #define FLAG_INLINESTUB    (1<<10)
  151. #define FLAG_NOFPU    (1<<11)
  152. #define FLAG_DIDERROR    (1<<12)
  153. #define FLAG_FPUONLY    (1<<13)
  154. #define FLAG_GNUPRAG    (1<<14)
  155.  
  156. #define FUNCFLAG_NORMAL    (1<<20)
  157. #define FUNCFLAG_TAG    (1<<21)
  158. #define FUNCFLAG_ALIAS    (1<<22)
  159.  
  160. #define MODUS_STUBTEXT      1
  161. #define MODUS_STUBCODE      2
  162. #define MODUS_LOCALDATA   3
  163. #define MODUS_PRAGMA      4
  164. #define MODUS_CSTUB      5
  165. #define MODUS_LVO     10    /* and 11 and 12 and 13         */
  166. #define MODUS_PROTO     20    /* and 21 and 22 and 23 and 24 and 25    */
  167. #define MODUS_INLINE     30    /* and 31 and 32 */
  168. #define MODUS_ERROR    100
  169.  
  170. /* call types for CallFunc */
  171. #define TAGMODE_NORMAL    0
  172. #define TAGMODE_TAGS    1
  173. #define TAGMODE_BOTH    2
  174.  
  175. /* types for pragma creation */
  176. #define PRAGMODE_PRAGLIB    1
  177. #define PRAGMODE_PRAGSLIB    2
  178. #define PRAGMODE_PRAGSPRAGS    3
  179. #define PRAGMODE_NONE        4
  180.  
  181. #define BIAS_OFFSET    6
  182.  
  183. #define EXTTYPESFILE    "PROGDIR:FD2Pragma.types"
  184. #define FDFILEEXTENSION    "_lib.fd"
  185.  
  186. #define PARAM     "FROM=FDFILE/A,SPECIAL/N,MODE/N,"            \
  187.         "TO/K,CLIB/K,HEADER/K,"                    \
  188.         "AMICALL/K,LIBCALL/K,AMITAGS/K,LIBTAGS/K,"        \
  189.         "COMMENT/S,EXTERNC/S,FPUONLY/S,NOFPU/S,PRIVATE/S,"    \
  190.         "SMALLDATA/S,SORTED/S,STORMFD/S,USESYSCALL/S"
  191.  
  192. STRPTR RegNames[] = {
  193. "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7",
  194. "a0", "a1", "a2", "a3", "a4", "a5", "a6", "a7",
  195. "fp0", "fp1", "fp2", "fp3", "fp4", "fp5", "fp6", "fp7",
  196. };
  197.  
  198. STRPTR RegNamesUpper[] = {
  199. "D0", "D1", "D2", "D3", "D4", "D5", "D6", "D7",
  200. "A0", "A1", "A2", "A3", "A4", "A5", "A6", "A7",
  201. "FP0", "FP1", "FP2", "FP3", "FP4", "FP5", "FP6", "FP7",
  202. };
  203.  
  204. enum Register_ID {
  205. REG_D0, REG_D1, REG_D2, REG_D3, REG_D4, REG_D5, REG_D6, REG_D7,
  206. REG_A0, REG_A1, REG_A2, REG_A3, REG_A4, REG_A5, REG_A6, REG_A7,
  207. REG_FP0, REG_FP1, REG_FP2, REG_FP3, REG_FP4, REG_FP5, REG_FP6, REG_FP7,
  208. MAXREG,
  209. };
  210. #define MAXREGNF    16
  211.  
  212. struct Args
  213. {
  214.   STRPTR FDFILE;
  215.   ULONG* SPECIAL;
  216.   ULONG* MODE;
  217.   STRPTR TO;
  218.   STRPTR CLIB;
  219.   STRPTR HEADER;
  220.   STRPTR AMICALL;
  221.   STRPTR LIBCALL;
  222.   STRPTR AMITAGS;
  223.   STRPTR LIBTAGS;
  224.   ULONG  COMMENT;
  225.   ULONG  EXTERNC;
  226.   ULONG  FPUONLY;
  227.   ULONG  NOFPU;
  228.   ULONG  PRIVATE;
  229.   ULONG  SMALLDATA;
  230.   ULONG  SORTED;
  231.   ULONG  STORMFD;
  232.   ULONG  USESYSCALL;
  233. };
  234.  
  235. struct ShortList {
  236.   struct ShortList    *Next;
  237. };
  238.  
  239. struct ShortListRoot {
  240.   struct ShortList    *First;
  241.   struct ShortList    *Last;
  242.   ULONG         Size;
  243. };
  244.  
  245. #define AMIPRAGFLAG_PUBLIC    (1<<0)    /* is a public function */
  246. #define AMIPRAGFLAG_A6USE    (1<<1)    /* A6 is used for this function */
  247. #define AMIPRAGFLAG_ARGCOUNT    (1<<2)    /* when double args, ... */
  248. #define AMIPRAGFLAG_DIDWARN    (1<<3)    /* We printed a argcount warning */
  249. #define AMIPRAGFLAG_FLOATARG    (1<<4)    /* It has a float argument */
  250. #define AMIPRAGFLAG_NOCLIB    (1<<5)    /* No clib definition found */
  251. #define AMIPRAGFLAG_CLIBARGCNT    (1<<6)    /* CLIB argument count error */
  252.  
  253. struct AmiPragma {
  254.   struct ShortList        List;
  255.   UWORD             Bias;
  256.   UWORD                Line;
  257.   ULONG                Flags;
  258.   STRPTR            FuncName;
  259.   STRPTR            TagName;
  260.   struct Pragma_AliasNames *    AliasName;  /* possible second name */
  261.   UWORD             NumArgs;  /* register numbers */
  262.   UWORD                CallArgs; /* argument number in fd file */
  263.   struct AmiArgs
  264.   {
  265.     STRPTR            ArgName;
  266.     UWORD            ArgReg;
  267.   } Args[MAXREG];
  268. };
  269.  
  270. struct Comment {
  271.   struct ShortList    List;
  272.   STRPTR        Data;
  273.   UWORD         Bias;
  274. };
  275.  
  276. struct PragList {
  277.   struct ShortList    List;
  278.   struct ShortListRoot    Data;        /* contains list of PragData */
  279.   STRPTR        Basename;
  280. };
  281.  
  282. struct PragData {
  283.   struct ShortList    List;
  284.   struct ShortListRoot    Name;
  285.   ULONG         NumNames;
  286.   ULONG         Bias;
  287.   ULONG         NumArgs;
  288.   UBYTE         ArgReg[MAXREG];
  289. };
  290.  
  291. struct FDData {
  292.   STRPTR    Name;
  293.   STRPTR    Basename;
  294.   ULONG     Bias;
  295.   ULONG     Mode;        /* 0 = Normal, != 0 is TagName */
  296.   ULONG     NumArgs;
  297.   UBYTE     ArgReg[MAXREG];
  298. };
  299.  
  300. #define CPP_TYPE_VOID        'v'    /* void,    VOID    */
  301. #define CPP_TYPE_BYTE        'c'    /* char,    BYTE    */
  302. #define CPP_TYPE_WORD        's'    /* short,    WORD    */
  303. #define CPP_TYPE_LONG        'j'    /* long,    LONG    */
  304. #define CPP_TYPE_FLOAT        'f'    /* float,    FLOAT    */
  305. #define CPP_TYPE_DOUBLE     'd'    /* double,    DOUBLE    */
  306. #define CPP_TYPE_STRUCTURE    0
  307. #define CPP_TYPE_VARARGS    'e'
  308.  
  309. /* Thse types are for string creation only */
  310. #define CPP_TYPE_ENUM        'E'
  311. #define CPP_TYPE_CONST        'C'
  312. #define CPP_TYPE_FUNCTION    'F'
  313. #define CPP_TYPE_POINTER    'P'
  314. #define CPP_TYPE_UNSIGNED    'U'
  315. #define CPP_TYPE_FUNCEND    'p'
  316. #define CPP_TYPE_REGISTER    'r'
  317.  
  318. #define CPP_FLAG_UNSIGNED    (1<<0)
  319. #define CPP_FLAG_CONST        (1<<1)
  320. #define CPP_FLAG_STRPTR     (1<<2)
  321. #define CPP_FLAG_POINTER    (1<<3)
  322. #define CPP_FLAG_ENUM        (1<<4)
  323. #define CPP_FLAG_STRUCT        (1<<5)
  324. #define CPP_FLAG_FUNCTION    (1<<6)
  325. /* STRPTR is defined different under C and CPP -> I have to create two
  326. names, one time unsigned char *, one time signed char *, when somewhere
  327. a STRPTR occurs */
  328.  
  329. struct CPP_NameType {
  330.   STRPTR    StructureName;     /* if a structure or enum only  */
  331.   STRPTR    FuncArgs;     /* arguments of function - unterminated */
  332.   STRPTR    TypeStart;     /* start of this type         */
  333.   UWORD     StructureLength; /* length of the structure name */
  334.   UWORD        ArgsLength;     /* length of FuncArgs         */
  335.   UWORD        TypeLength;     /* length of this type         */
  336.   UWORD        FullLength;     /* length of complete type     */
  337.   UWORD     PointerDepth;     /* number of * in type      */
  338.   UBYTE     Type;         /* see above defines         */
  339.   UBYTE     Flags;         /* see above flags         */
  340. };
  341.  
  342. struct ClibData {
  343.   struct ClibData *    Next;
  344.   STRPTR        FuncName;
  345.   ULONG            NumArgs;
  346.   struct CPP_NameType    ReturnType;
  347.   struct CPP_NameType    Args[MAXREG];
  348. };
  349.  
  350. struct CPP_ExternNames { /* structure for EXTTYPESFILE data */
  351.   struct CPP_ExternNames * Next;
  352.   STRPTR           Type;    /* The unknown type */
  353.   struct CPP_NameType       NameType;    /* The replacement */
  354. };
  355.  
  356. struct CPP_TypeField {
  357.   STRPTR    Text;
  358.   UWORD     Length;
  359.   UBYTE     Flags;
  360.   UBYTE     Type;
  361. };
  362.  
  363. struct Proto_LibTypes {
  364.   STRPTR    BaseName;
  365.   STRPTR    StructureName;
  366. };
  367.  
  368. struct Pragma_ExecpNames { /* TagName 0 is valid as well */
  369.   STRPTR    FunctionName;
  370.   STRPTR    TagName;
  371. };
  372.  
  373. struct Pragma_AliasNames {
  374.   STRPTR    FunctionName;
  375.   STRPTR    AliasName;
  376.   ULONG        Type;
  377. };
  378.  
  379. #define NTP_NORMAL    0    /* no tags/args     */
  380. #define NTP_TAGS    1    /* TagFunction        */
  381. #define NTP_ARGS    2    /* ArgFunction        */
  382. #define NTP_UNKNOWN    3    /* CommentFunction    */
  383.  
  384. struct NameList {
  385.   struct ShortList    List;
  386.   ULONG         Type;    /* set by OptimizeFDData */
  387.   STRPTR        NormName;
  388.   STRPTR        PragName;
  389. };
  390.  
  391. struct InOut {
  392.   ULONG  file;
  393.   STRPTR pos;
  394.   STRPTR buf;
  395.   ULONG  size;
  396. };
  397.  
  398. struct RememberMem {
  399.   struct RememberMem *    rm_Next;
  400.   ULONG            rm_Size;
  401. };
  402.  
  403. struct RDArgs * rda            = 0;
  404. struct InOut    in            = {0,0,0,0},
  405.         out            = {0,0,0,5120};
  406. struct ClibData *    clibdata    = 0;
  407. struct FileInfoBlock *    fib        = 0;
  408. struct ShortListRoot    AmiPragma    = {0,0,sizeof(struct AmiPragma)},
  409.             Comment     = {0,0,sizeof(struct Comment)};
  410. struct RememberMem *    remember    = 0;
  411. struct CPP_ExternNames *extnames    = 0;
  412. ULONG        oldfh            = 0;
  413. ULONG        lock            = 0;
  414. STRPTR        BaseName        = 0;
  415. STRPTR        ShortBaseName        = 0;
  416. STRPTR        ShortBaseNameUpper    = 0;
  417. ULONG        DosVersion        = 37; /* force OS2.0 */
  418. STRPTR        HEADER            = 0;
  419. ULONG        headersize        = 0;
  420. ULONG        Flags            = 0;
  421. ULONG        Output_Error        = 1; /* Output error occured when 0 */
  422. ULONG        tagfuncs        = 0; /* are there some tagfuncs in FD */
  423.  
  424. /* Prototypes for the functions */
  425. STRPTR DupString(STRPTR, ULONG);
  426. STRPTR AllocListMem(ULONG);
  427. void FreeListMem(void);
  428. STRPTR SkipBlanks(STRPTR);
  429. STRPTR SkipBlanksRet(STRPTR);
  430. STRPTR SkipName(STRPTR);
  431. STRPTR GetBaseType(void);
  432. ULONG  CloseDest(STRPTR);
  433. ULONG  MakeTagFunction(struct AmiPragma *);
  434. void   MakeLines(STRPTR, ULONG);
  435. ULONG  SpecialFuncs(void);
  436. void   SortFDList(void);
  437. ULONG  ScanFDFile(void);
  438. LONG   ScanTypes(STRPTR, ULONG);
  439. void   FindHeader(void);
  440. ULONG  GetRegisterData(struct AmiPragma *);
  441. UWORD  GetFRegisterData(struct AmiPragma *);
  442. ULONG  OutputXDEF(STRPTR, ...);
  443. UWORD *AsmStackCopy(UWORD *, struct AmiPragma *, ULONG, ULONG);
  444. /* ------------------------------------------------------------------ */
  445. void   DoError(UBYTE, ULONG, ...);
  446. ULONG  Out(ULONG);
  447. ULONG  DoOutput(STRPTR, ...);
  448. ULONG  DoOutputDirect(APTR, ULONG);
  449. /* ------------------------------------------------------------------ */
  450. struct ShortList *NewItem(struct ShortListRoot *);
  451. struct ShortList *RemoveItem(struct ShortListRoot *, struct ShortList *);
  452. void          AddItem(struct ShortListRoot *, struct ShortList *);
  453. /* ------------------------------------------------------------------ */
  454. typedef ULONG (*FuncType)(struct AmiPragma *, ULONG, STRPTR);
  455.  
  456. ULONG FuncAMICALL(struct AmiPragma *, ULONG, STRPTR);
  457. ULONG FuncLIBCALL(struct AmiPragma *, ULONG, STRPTR);
  458. ULONG FuncAsmText(struct AmiPragma *, ULONG, STRPTR);
  459. ULONG FuncAsmCode(struct AmiPragma *, ULONG, STRPTR);
  460. ULONG FuncCSTUBS (struct AmiPragma *, ULONG, STRPTR);
  461. ULONG FuncLVOXDEF(struct AmiPragma *, ULONG, STRPTR);
  462. ULONG FuncLVO     (struct AmiPragma *, ULONG, STRPTR);
  463. ULONG FuncLocCode(struct AmiPragma *, ULONG, STRPTR);
  464. ULONG FuncLocText(struct AmiPragma *, ULONG, STRPTR);
  465. ULONG FuncInline (struct AmiPragma *, ULONG, STRPTR);
  466. ULONG CallFunc(ULONG, STRPTR, FuncType);
  467. /* ------------------------------------------------------------------ */
  468. LONG   AddClibEntry(STRPTR, STRPTR, ULONG);
  469. LONG   ScanClibFile(STRPTR, STRPTR);
  470. LONG   IsCPPType(struct CPP_NameType *, UBYTE);
  471. LONG   GetCPPType(struct CPP_NameType *, STRPTR);
  472. struct ClibData *GetClibFunc(STRPTR, struct AmiPragma *, ULONG);
  473. LONG   CheckKeyword(STRPTR, STRPTR, LONG);
  474. ULONG  CopyCPPType(STRPTR, ULONG, struct ClibData *, struct AmiArgs *);
  475. ULONG  OutClibType(struct CPP_NameType *, STRPTR);
  476. /* ------------------------------------------------------------------ */
  477. ULONG CallPrag(ULONG, STRPTR, FuncType);
  478. ULONG CreatePragmaFile(STRPTR, STRPTR, STRPTR, STRPTR, ULONG);
  479. ULONG CreateCSTUBS(void);
  480. ULONG CreateLVOFile(ULONG);
  481. ULONG CreateAsmStubs(ULONG, ULONG);
  482. ULONG CreateProtoFile(ULONG);
  483. ULONG CreateLocalData(STRPTR, ULONG, STRPTR, ULONG);
  484. ULONG CreateInline(ULONG);
  485. /* ------------------------------------------------------------------ */
  486. ULONG GetName(struct NameList *, struct ShortListRoot *, ULONG);
  487. ULONG MakeFD(struct PragList *);
  488. void  OptimizeFDData(struct PragData *);
  489. UBYTE GetHexValue(UBYTE);
  490. UBYTE GetDoubleHexValue(UBYTE *);
  491. ULONG AddFDData(struct ShortListRoot *, struct FDData *);
  492. ULONG GetLibData(struct FDData *);
  493. ULONG GetFlibData(struct FDData *);
  494. ULONG GetAmiData(struct FDData *);
  495. ULONG CreateFDFile(STRPTR, STRPTR);
  496. /* ------------------------------------------------------------------ */
  497. void main(void);
  498. void End(ULONG);
  499.  
  500. enum {
  501. ERR_TAGFUNC_NEEDS_ARGUMENT,
  502. ERR_CANNOT_CONVERT_PRAGMA_TAGCALL,
  503. ERR_TAG_DEF_WITHOUT_PRAGMA,
  504. ERR_BASENAME_DECLARED_TWICE,
  505. ERR_EXPECTED_SLASH_IN_BASENAME,
  506. ERR_EXPECTED_BASENAME,
  507. ERR_EXPECTED_BIAS_VALUE,
  508. ERR_ASSUMING_POSITIVE_BIAS_VALUE,
  509. ERR_MISSING_FUNCTION_NAME,
  510. ERR_EXPECTED_OPEN_BRACKET,
  511. ERR_TO_MUCH_ARGUMENTS,
  512. ERR_EXPECTED_ARGUMENT_NAME,
  513. ERR_EXPECTED_CLOSE_BRACKET,
  514. ERR_EXPECTED_REGISTER_NAME,
  515. ERR_A7_NOT_ALLOWED,
  516. ERR_REGISTER_USED_TWICE,
  517. ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER,
  518. ERR_ASSUMING_BIAS_OF_30,
  519. ERR_EXTRA_CHARACTERS,
  520. ERR_MISSING_BASENAME,
  521. ERR_WRITING_FILE,
  522. ERR_EXPECTED_COMMA,
  523. ERR_DIFFERENT_TO_PREVIOUS,
  524. ERR_UNKNOWN_VARIABLE_TYPE,
  525. ERR_UNKNOWN_ERROR,
  526. ERR_MISSING_END,
  527. ERR_PROTOTYPE_MISSING,
  528. ERR_NOPROTOTYPES_FILE,
  529. ERR_UNKNOWN_DIRECTIVE,
  530. ERR_INLINE_A4_AND_A5,
  531. ERR_INLINE_D7_AND_A45,
  532. ERR_MISSING_SHORTBASENAME,
  533. ERR_USER_ABORT,
  534. ERR_A6_NOT_ALLOWED,
  535. ERR_EMPTY_FILE,
  536. ERR_FLOATARG_NOT_ALLOWED,
  537. ERR_WRONG_TYPES_LINE,
  538. ERR_LONG_DOUBLE,
  539. ERR_CLIB_ARG_COUNT,
  540. };
  541.  
  542. struct ErrField {
  543.   UBYTE  Type;    /* 0 = Error, 1 = Warning */
  544.   UBYTE  Skip;
  545.   STRPTR Error;
  546. } Errors[] = {
  547. {1, 1, "Tag function must have arguments."},
  548. {1, 1, "Cannot convert pragma name into tag name."},
  549. {1, 1, "Tag definition without preceding Pragma."},
  550. {1, 0, "Basename declared twice."},
  551. {1, 0, "Expected preceding _ in Basename."},
  552. {1, 1, "Expected Basename."},
  553. {1, 0, "Expected Bias value."},
  554. {1, 0, "Assuming positive bias value."},
  555. {1, 1, "Missing function name."},
  556. {1, 1, "Expected '('."},
  557. {1, 1, "Too much arguments."},
  558. {1, 1, "Expected argument name."},
  559. {1, 1, "Expected ')'."},
  560. {1, 1, "Expected register name."},
  561. {1, 1, "A7 not allowed as argument register."},
  562. {1, 1, "Register used twice."},
  563. {1, 0, "Number of arguments != number of registers."},
  564. {1, 0, "Assuming bias of 30."},
  565. {1, 1, "Extra characters."},
  566. {0, 0, "Missing Basename in FD file."},
  567. {0, 0, "Failed to write destination file."},
  568. {1, 1, "Expected ','."},
  569. {0, 1, "Data different to previous given."},
  570. {1, 0, "Unknown type of argument %ld\n"},
  571. {0, 0, "Unknown problem: program error or corrupt input data."},
  572. {1, 0, "Missing ##end."},
  573. {1, 0, "Prototype for function \"%s\" not found."},
  574. {0, 0, "No prototypes file (CLIB parameter) was specified."},
  575. {1, 1, "Unknown directive '##%s' found."},
  576. {1, 0, "Usage of both A4 and A5 is not supported."},
  577. {1, 0, "Usage of both D7 and A4 or A5 is not supported."},
  578. {0, 0, "Missing Basename in FD file and FD filename."},
  579. {0, 0, "User aborted operation."},
  580. {1, 0, "A6 not allowed as argument register."},
  581. {1, 0, "Empty or partial file deleted."},
  582. {1, 1, "Floating point arguments not allowed."},
  583. {0, 0, "Wrong definition in external type definition file."},
  584. {1, 0, "Cannot determine if FPU argument is double or single."},
  585. {1, 0, "CLIB argument count differs for %s (%ld != %ld)."},
  586. };
  587.  
  588. struct CPP_TypeField CPP_Field[] = {
  589. {"long",    4, 0,            CPP_TYPE_LONG},
  590. {"ULONG",    5, CPP_FLAG_UNSIGNED,    CPP_TYPE_LONG},
  591. {"LONGBITS",    8, CPP_FLAG_UNSIGNED,    CPP_TYPE_LONG},
  592. {"CPTR",    4, CPP_FLAG_UNSIGNED,    CPP_TYPE_LONG},
  593. {"Tag",     3, CPP_FLAG_UNSIGNED,    CPP_TYPE_LONG},
  594. {"Object",    6, CPP_FLAG_UNSIGNED,    CPP_TYPE_LONG},
  595. {"LONG",    4, 0,            CPP_TYPE_LONG},
  596. {"BPTR",    4, 0,            CPP_TYPE_LONG},
  597. {"BSTR",    4, 0,            CPP_TYPE_LONG},
  598. {"short",    5, 0,            CPP_TYPE_WORD},
  599. {"CxObj",    5, 0,            CPP_TYPE_LONG},
  600. {"CxMsg",    5, 0,            CPP_TYPE_LONG},
  601. {"USHORT",    6, CPP_FLAG_UNSIGNED,    CPP_TYPE_WORD},
  602. {"UWORD",    5, CPP_FLAG_UNSIGNED,    CPP_TYPE_WORD},
  603. {"UCOUNT",    6, CPP_FLAG_UNSIGNED,    CPP_TYPE_WORD},
  604. {"WORDBITS",    8, CPP_FLAG_UNSIGNED,    CPP_TYPE_WORD},
  605. {"RPTR",    4, CPP_FLAG_UNSIGNED,    CPP_TYPE_WORD},
  606. {"SHORT",    5, 0,            CPP_TYPE_WORD},
  607. {"COUNT",    5, 0,            CPP_TYPE_WORD},
  608. {"WORD",    4, 0,            CPP_TYPE_WORD},
  609. {"BOOL",    4, 0,            CPP_TYPE_WORD},
  610. {"char",    4, 0,            CPP_TYPE_BYTE},
  611. {"UBYTE",    5, CPP_FLAG_UNSIGNED,    CPP_TYPE_BYTE},
  612. {"TEXT",    4, CPP_FLAG_UNSIGNED,    CPP_TYPE_BYTE},
  613. {"BYTEBITS",    8, CPP_FLAG_UNSIGNED,    CPP_TYPE_BYTE},
  614. {"BYTE",    4, 0,            CPP_TYPE_BYTE},
  615. {"void",    4, 0,            CPP_TYPE_VOID},
  616. {"VOID",    4, 0,            CPP_TYPE_VOID},
  617. {"float",    5, 0,            CPP_TYPE_FLOAT},
  618. {"FLOAT",    5, 0,            CPP_TYPE_FLOAT},
  619. {"double",    6, 0,            CPP_TYPE_DOUBLE},
  620. {"DOUBLE",    6, 0,            CPP_TYPE_DOUBLE},
  621. {"STRPTR",    6, CPP_FLAG_POINTER|CPP_FLAG_STRPTR,    CPP_TYPE_BYTE},
  622. {"APTR",    4, CPP_FLAG_POINTER,    CPP_TYPE_VOID},
  623. {"ClassID",    7, CPP_FLAG_POINTER|CPP_FLAG_UNSIGNED,    CPP_TYPE_BYTE},
  624. {"PLANEPTR",    8, CPP_FLAG_POINTER|CPP_FLAG_UNSIGNED,    CPP_TYPE_BYTE},
  625. {"DisplayInfoHandle",17,CPP_FLAG_POINTER,CPP_TYPE_VOID},
  626. {0,0,0,0},
  627. };
  628.  
  629. struct Proto_LibTypes Proto_LibTypes[] = {
  630. {"DOSBase",            "DosLibrary"},
  631. {"SysBase",            "ExecBase"},
  632. {"ExpansionBase",        "ExpansionBase"},
  633. {"GfxBase",            "GfxBase"},
  634. {"IntuitionBase",        "IntuitionBase"},
  635. {"LocaleBase",            "LocaleBase"},
  636. {"MathIeeeDoubBasBase",     "MathIEEEBase"},
  637. {"MathIeeeDoubTransBase",    "MathIEEEBase"},
  638. {"MathIeeeSingBasBase",     "MathIEEEBase"},
  639. {"MathIeeeSingTransBase",    "MathIEEEBase"},
  640. {"RealTimeBase",        "RealTimeBase"},
  641. {"RexxSysBase",         "RxsLib"},
  642. {"UtilityBase",         "UtilityBase"},
  643. /* resources - The Node entries may be correct, but I don't know it. */
  644. /*    {"BattClockBase",        "Node"}, */
  645. /*    {"BattMemBase",            "Node"}, */
  646. {"DiskBase",            "DiskResource"},
  647. /*    {"MiscBase",            "Node"}, */
  648. /*    {"PotgoBase",            "Node"}, */
  649. /* devices */
  650. {"ConsoleDevice",        "Device"},
  651. {"InputBase",            "Device"},
  652. {"RamdriveDevice",        "Device"},
  653. {"TimerBase",            "Device"},
  654. /* non default Basenames */
  655. {"DatamasterBase",        "DatamasterBase"},
  656. {"PPBase",            "PPBase"},
  657. {"ReqToolsBase",        "ReqToolsBase"},
  658. {"UnpackBase",            "UnpackLibrary"},
  659. {"xfdMasterBase",        "xfdMasterBase"},
  660. {"GTXBase",            "GTXBase"},
  661. {0, 0},
  662. };
  663.  
  664. /* CachePostDMA, CachePreDMA are done by #?DMA check */
  665. struct Pragma_ExecpNames Pragma_ExecpNames[] = {
  666. {"VFWritef",        "FWritef"},
  667. {"VFPrintf",        "FPrintf"},
  668. {"VPrintf",        "Printf"},
  669. /* {"RefreshDTObjectA",    "RefreshDTObjects"}, */
  670. {"ReadArgs",        0},
  671. {"FreeArgs",        0},
  672. {"CloneTagItems",    0},
  673. {"FindTagItem",        0},
  674. {"FreeTagItems",    0},
  675. {"GetTagData",        0},
  676. {"PackBoolTags",    0},
  677. {"PackStructureTags",    0},
  678. {"UnpackStructureTags",    0},
  679. {0,0},
  680. };
  681.  
  682. /* for double tagcall names (currently only necessary for dos.library) */
  683. struct Pragma_AliasNames Pragma_AliasNames[] = {
  684. {"AllocDosObject",    "AllocDosObjectTagList",    FUNCFLAG_NORMAL},
  685. {"CreateNewProc",    "CreateNewProcTagList",        FUNCFLAG_NORMAL},
  686. {"NewLoadSeg",        "NewLoadSegTagList",        FUNCFLAG_NORMAL},
  687. {"SystemTagList",    "System",            FUNCFLAG_NORMAL},
  688. {0,0,0},
  689. };
  690.  
  691. STRPTR DupString(STRPTR Str, ULONG Len)
  692. {
  693.   STRPTR res;
  694.   if((res = AllocListMem(Len+1)))
  695.   {
  696.     CopyMem(Str, res, Len);
  697.     res[Len] = '\0';
  698.   }
  699.   return res;
  700. }
  701.  
  702. STRPTR AllocListMem(ULONG size)
  703. {
  704.   struct RememberMem *r;
  705.  
  706.   size += sizeof(struct RememberMem);
  707.  
  708.   if((r = (struct RememberMem *) AllocMem(size, MEMF_ANY|MEMF_CLEAR)))
  709.   {
  710.     r->rm_Next = remember;
  711.     r->rm_Size = size;
  712.     remember = r;
  713.     return ((STRPTR) r)+sizeof(struct RememberMem);
  714.   }
  715.   return 0;
  716. }
  717.  
  718. void FreeListMem(void)
  719. {
  720.   struct RememberMem *r;
  721.  
  722.   r = remember;
  723.  
  724.   while(r)
  725.   {
  726.     struct RememberMem *s;
  727.     s = r;
  728.     r = r->rm_Next;
  729.     
  730.     FreeMem(s, s->rm_Size);
  731.   }
  732. }
  733.  
  734. STRPTR SkipBlanks(STRPTR OldPtr)
  735. {
  736.   while(*OldPtr == ' ' || *OldPtr == '\t')
  737.     ++OldPtr;
  738.   return OldPtr;
  739. }
  740.  
  741. STRPTR SkipBlanksRet(STRPTR OldPtr)
  742. {
  743.   while(*OldPtr == ' ' || *OldPtr == '\t' || *OldPtr == '\n')
  744.     ++OldPtr;
  745.   return OldPtr;
  746. }
  747.  
  748. /*
  749.     This function is used to skip over variable names.
  750.  
  751.     Inputs: OldPtr  - pointer to the beginning of a string.
  752.  
  753.     Result: Pointer to the first character of the string, that is not one
  754.         of a-z, A-Z, 0-9 or the underscore.
  755. */
  756.  
  757. STRPTR SkipName(STRPTR OldPtr)
  758. {
  759.   while(isalnum(*OldPtr) || *OldPtr == '_')
  760.     ++OldPtr;
  761.   return OldPtr;
  762. }
  763.  
  764. STRPTR GetBaseType(void)
  765. {
  766.   ULONG i;
  767.   STRPTR str = "Library";
  768.  
  769.   for(i = 0; BaseName && Proto_LibTypes[i].BaseName; ++i)
  770.   {
  771.     if(!(strcmp(Proto_LibTypes[i].BaseName, BaseName)))
  772.     {
  773.       str = Proto_LibTypes[i].StructureName; break;
  774.     }
  775.   }
  776.   return str;
  777. }
  778.  
  779. ULONG CloseDest(STRPTR name)
  780. {
  781.   if(out.file)
  782.   {
  783.     Out(out.size);    /* clears Output-Buffer */
  784.     Close(out.file);
  785.     out.file = 0;
  786.  
  787.     if(!(Flags & FLAG_DONE) || !Output_Error || CTRL_C)
  788.     {
  789.       DoError(ERR_EMPTY_FILE, 0);
  790.       DeleteFile(name); return 0;
  791.     }
  792.     Flags &= ~FLAG_DONE;    /* clear the flag */
  793.   }
  794.   else
  795.     return 0;
  796.   return 1;
  797. }
  798.  
  799. ULONG MakeTagFunction(struct AmiPragma *ap)
  800. {
  801.   ULONG len = strlen(ap->FuncName), i=0;
  802.  
  803. #ifdef DEBUG_OLD
  804.   VPrintf("MakeTagFunction:\n", 0);
  805. #endif
  806.  
  807.   ++tagfuncs;
  808.  
  809.   while(Pragma_ExecpNames[i].FunctionName && /* check the exception names */
  810.   strcmp(ap->FuncName, Pragma_ExecpNames[i].FunctionName))
  811.     ++i;
  812.  
  813.   if(Pragma_ExecpNames[i].FunctionName)
  814.   {
  815.     if(!(ap->TagName = Pragma_ExecpNames[i].TagName));
  816.       --tagfuncs;
  817.   }
  818.   else if(ap->FuncName[len-1] == 'A')
  819.   {
  820.     if(!strcmp(ap->FuncName+len-3, "DMA")) /* skip names with DMA at end */
  821.     { --tagfuncs; return 1;}
  822.     if(!(ap->TagName = DupString(ap->FuncName, len-1)))
  823.       return 0;
  824.   }
  825.   else if(!strcmp(ap->FuncName + len-7, "TagList"))
  826.   {
  827.     if(!(ap->TagName = DupString(ap->FuncName, len-3)))
  828.       return 0;
  829.     ap->TagName[len-4] = 's';
  830.   }
  831.   else if(!strcmp(ap->FuncName + len-4, "Args"))
  832.   {
  833.     if(!(ap->TagName = DupString(ap->FuncName, len-4)))
  834.       return 0;
  835.   }
  836.   else if(!stricmp(ap->Args[ap->NumArgs-1].ArgName, "tags") ||
  837.   !stricmp(ap->Args[ap->NumArgs-1].ArgName, "taglist"))
  838.   {
  839.     if(!(ap->TagName = DupString(ap->FuncName, len+4)))
  840.       return 0;
  841.     CopyMem("Tags", ap->TagName + len, 5);
  842.   }
  843.   else if(!stricmp(ap->Args[ap->NumArgs-1].ArgName, "args"))
  844.   {
  845.     if(!(ap->TagName = DupString(ap->FuncName, len+4)))
  846.       return 0;
  847.     CopyMem("Args", ap->TagName + len, 5);
  848.   }
  849.   else
  850.     --tagfuncs; /* not a tagfunction, incrementing was false, undo it */
  851.  
  852.   return 1;
  853. }
  854.  
  855. void MakeLines(STRPTR buffer, ULONG size)
  856. {
  857.   if(size && buffer)
  858.   {
  859.     /* make a real C++ zero string ending line */
  860.     while(--size)
  861.     {
  862.       if(*buffer == '\n')
  863.         *buffer = '\0';
  864.       ++buffer;
  865.     }
  866.     *buffer = '\0';
  867.   }
  868. }
  869.  
  870. /* Do any special functions, which cannot be done with other exception
  871.    stuff - currently only dos.library DoPkt function. */
  872. ULONG SpecialFuncs(void)
  873. {
  874.   struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.Last;
  875.  
  876.   if(ap->Bias == 0xF0 && !strcmp("DoPkt", ap->FuncName))
  877.   {
  878.     struct AmiPragma *d;
  879.     ULONG i;
  880.  
  881.     for(i = 0; i < 5; ++i)
  882.     {
  883.       if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
  884.     return 0;
  885.       CopyMem(ap, d, sizeof(struct AmiPragma));
  886.       d->FuncName = DupString(ap->FuncName, 6);
  887.       d->FuncName[5] = '0'+i;
  888.       d->NumArgs = d->CallArgs = i + 2;
  889.       AddItem(&AmiPragma, (struct ShortList *) d);
  890.     }
  891.   }
  892.   return 1;
  893. }
  894.  
  895. void SortFDList(void)
  896. {
  897.   struct AmiPragma *ap = (struct AmiPragma *) AmiPragma.First, *ap2, *ap3;
  898.   AmiPragma.First = AmiPragma.Last = 0;
  899.  
  900.   while(ap)
  901.   {
  902.     ap3 = 0;
  903.     ap2 = (struct AmiPragma *) AmiPragma.First;
  904.  
  905.     /* for FD2Inline style we need to use strcmp instead of stricmp here */
  906.     while(ap2 && stricmp(ap2->FuncName, ap->FuncName) < 0)
  907.     {
  908.       ap3 = ap2;
  909.       ap2 = (struct AmiPragma *) ap2->List.Next;
  910.     }
  911.  
  912.     ap2 = ap;
  913.     ap = (struct AmiPragma *) ap->List.Next;
  914.  
  915.     if(ap3)
  916.     {
  917.       ap2->List.Next = (struct ShortList *) ap3->List.Next;
  918.       ap3->List.Next = (struct ShortList *) ap2;
  919.     }
  920.     else
  921.     {
  922.       ap2->List.Next = AmiPragma.First;
  923.       AmiPragma.First = (struct ShortList *) ap2;
  924.     }
  925.     if(ap && !ap->List.Next)
  926.       AmiPragma.Last = (struct ShortList *) ap2;
  927.   }
  928. }
  929.  
  930. ULONG ScanFDFile(void)
  931. {
  932. #ifdef DEBUG_OLD
  933.   VPrintf("ScanFDFile:\n", 0);
  934. #endif
  935.  
  936.   ULONG _public = 1;
  937.   LONG bias = -1;
  938.   ULONG linenum, len;
  939.   ULONG actcom = 0;
  940.  
  941.   for(linenum = 1; !CTRL_C && in.pos < in.buf + in.size; ++linenum)
  942.   {
  943.     if(*in.pos == '*')         /*  Comment   */
  944.     {
  945.       STRPTR oldpos = in.pos;
  946. #ifdef DEBUG_OLD
  947.   VPrintf("ScanFDFile: found a comment\n", 0);
  948. #endif
  949.       in.pos = SkipBlanks(in.pos+1);
  950.       if(!strnicmp(in.pos, "tagcall", 7))  /*  Tag to create?  */
  951.       {
  952.     struct AmiPragma *prevpragma = (struct AmiPragma *)
  953.         AmiPragma.Last;
  954.  
  955.     in.pos = SkipBlanks(in.pos + 7);
  956.     if(!prevpragma)
  957.     {
  958.       DoError(ERR_TAG_DEF_WITHOUT_PRAGMA, linenum);
  959.       ++in.pos;
  960.       continue;
  961.     }
  962.  
  963.     if(!prevpragma->NumArgs)
  964.     {
  965.       DoError(ERR_TAGFUNC_NEEDS_ARGUMENT, linenum);
  966.       ++in.pos;
  967.       continue;
  968.     }
  969.  
  970.     /* Get the tag functions name. */
  971.  
  972.     if(!prevpragma->TagName && (_public || (Flags & FLAG_PRIVATE)))
  973.       ++tagfuncs;
  974.  
  975.     if(*in.pos)
  976.     {
  977.       STRPTR oldptr, tptr = prevpragma->TagName;
  978.  
  979.       len = strlen(prevpragma->FuncName)+strlen(in.pos)+1;
  980.       if(!(prevpragma->TagName = DupString(prevpragma->FuncName, len)))
  981.         return 0;
  982.  
  983.       if(*in.pos == '-')
  984.       {
  985.         STRPTR removeptr;
  986.  
  987.         oldptr = in.pos = SkipBlanks(in.pos+1);
  988.         in.pos = SkipName(in.pos);
  989.         if((len = in.pos-oldptr))
  990.         {
  991.           removeptr = prevpragma->TagName+strlen(prevpragma->TagName)-len;
  992.           if(strncmp(removeptr, oldptr, len))
  993.           {
  994. #ifdef DEBUG_OLD
  995.         {
  996.           struct data {STRPTR a;STRPTR b;ULONG c;} a;
  997.           a.a = removeptr;
  998.           a.b = oldptr;
  999.           a.c = len;
  1000.           VPrintf("ScanFDFile: *tagcall -: %s, %s, %ld\n", &a);
  1001.         }
  1002. #endif
  1003.         DoError(ERR_CANNOT_CONVERT_PRAGMA_TAGCALL, linenum);
  1004.         prevpragma->TagName = tptr;
  1005.         ++in.pos;
  1006.         continue;
  1007.           }
  1008.  
  1009.           *removeptr = '\0';
  1010.         }
  1011.         in.pos = SkipBlanks(in.pos);
  1012.       }
  1013.       if(*in.pos == '+')
  1014.         in.pos = SkipBlanks(in.pos+1);
  1015.       else
  1016.         *in.pos = toupper(*in.pos);
  1017.  
  1018.       in.pos = SkipName((oldptr = in.pos));
  1019.       len = in.pos-oldptr;
  1020.       if(len)
  1021.       {
  1022.         ULONG a = strlen(prevpragma->TagName);
  1023.         CopyMem(oldptr, prevpragma->TagName+a, len);
  1024.         prevpragma->TagName[a+len] = '\0';
  1025.       }
  1026.     }
  1027.     else if(!prevpragma->TagName)
  1028.     {
  1029.       len = strlen(prevpragma->FuncName);
  1030.       if(!(prevpragma->TagName = DupString(prevpragma->FuncName, len+4)))
  1031.         return 0;
  1032.       CopyMem("Tags", prevpragma->TagName + len, 5);
  1033.     }
  1034.       }
  1035.       else
  1036.       {
  1037.     if(actcom)
  1038.       *(oldpos-1) = '\n';
  1039.     else if(Flags & FLAG_DOCOMMENT)
  1040.     {
  1041.       struct Comment *d;
  1042.       if(!(d = (struct Comment *) NewItem(&Comment)))
  1043.         return 0;
  1044.       d->Bias = bias;
  1045.       d->Data = oldpos;
  1046.       AddItem(&Comment, (struct ShortList *) d);
  1047.       actcom = 1;
  1048.     }
  1049.     while(*in.pos)
  1050.       ++in.pos;
  1051.       }
  1052.     }
  1053.     else if(*in.pos == '#' && in.pos[1] == '#')
  1054.     {
  1055.       in.pos += 2;
  1056.       actcom = 0; /* no Comment */
  1057.  
  1058.       if(!strnicmp(in.pos, "base", 4))
  1059.       {
  1060. #ifdef DEBUG_OLD
  1061.   VPrintf("ScanFDFile: found ##base\n", 0);
  1062. #endif
  1063.         STRPTR oldptr;
  1064.  
  1065.         if(BaseName)
  1066.       DoError(ERR_BASENAME_DECLARED_TWICE, linenum);
  1067.  
  1068.         in.pos = SkipBlanks(in.pos+4);
  1069.         if(*in.pos != '_')
  1070.       DoError(ERR_EXPECTED_SLASH_IN_BASENAME, linenum);
  1071.         else
  1072.       ++in.pos;
  1073.  
  1074.         in.pos = SkipName((oldptr = in.pos));
  1075.         if((len = in.pos-oldptr))
  1076.         {
  1077.       if(!(BaseName = DupString(oldptr, len)))
  1078.         return 0;
  1079.       if(!ShortBaseName && !(ShortBaseName = DupString(BaseName, len-4)))
  1080.         return 0;
  1081.         }
  1082.         else
  1083.       DoError(ERR_EXPECTED_BASENAME, linenum);
  1084.       }
  1085.       else if(!strnicmp(in.pos, "bias", 4))
  1086.       {
  1087. #ifdef DEBUG_OLD
  1088.   VPrintf("ScanFDFile: found ##bias\n", 0);
  1089. #endif
  1090.         STRPTR ptr;
  1091.         LONG newbias;
  1092.  
  1093.         in.pos += 5;
  1094.         newbias = strtol(in.pos, &ptr, 10);
  1095.         if(ptr == in.pos)
  1096.       DoError(ERR_EXPECTED_BIAS_VALUE, linenum);
  1097.         else if(newbias < 0)
  1098.         {
  1099.       DoError(ERR_ASSUMING_POSITIVE_BIAS_VALUE, linenum);
  1100.       bias = -newbias;
  1101.         }
  1102.         else
  1103.       bias = newbias;
  1104.         in.pos = SkipName(in.pos);
  1105.       }
  1106.       else if(!strnicmp(in.pos, "end", 3))
  1107.       {
  1108.         bias = 0; break;
  1109.       }
  1110.       else if(!strnicmp(in.pos, "shadow", 6)) /* introduced by Storm */
  1111.       {
  1112.         in.pos += 6;
  1113.         bias -= BIAS_OFFSET;
  1114.       }
  1115.       else if(!strnicmp(in.pos, "public", 6))
  1116.       {
  1117.         in.pos += 6;
  1118.         _public = 1;
  1119.       }
  1120.       else if(!strnicmp(in.pos, "private", 7))
  1121.       {
  1122.         in.pos += 7;
  1123.         _public = 0;
  1124.       }
  1125.       else
  1126.         DoError(ERR_UNKNOWN_DIRECTIVE, linenum, in.pos);
  1127.     }
  1128.     else
  1129.     {
  1130. #ifdef DEBUG_OLD
  1131.   VPrintf("ScanFDFile: scan Function\n", 0);
  1132. #endif
  1133.       STRPTR oldptr;
  1134.       struct AmiPragma ap;
  1135.  
  1136.       memset(&ap, 0, sizeof(struct AmiPragma));
  1137.       actcom = 0;
  1138.  
  1139.       oldptr = in.pos = SkipBlanks(in.pos);
  1140.       in.pos = SkipName(oldptr);
  1141.       if(!(len = in.pos-oldptr))
  1142.       {
  1143.     DoError(ERR_MISSING_FUNCTION_NAME, linenum);
  1144.     ++in.pos;
  1145.     continue;
  1146.       }
  1147.  
  1148.       ap.FuncName = oldptr;
  1149.  
  1150.       in.pos = SkipBlanks(in.pos);
  1151.       if(*in.pos != '(')
  1152.       {
  1153.     DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
  1154.     ++in.pos;
  1155.     continue;
  1156.       }
  1157.  
  1158.       *in.pos = '\0'; /* create c string of FunctionName */
  1159.  
  1160. #ifdef DEBUG_OLD
  1161.   VPrintf("ScanFDFile: found function %s\n", &ap.FuncName);
  1162. #endif
  1163.  
  1164.       do
  1165.       {
  1166.     oldptr = in.pos = SkipBlanks(in.pos+1);
  1167.  
  1168.     if(*in.pos == ')' && !ap.CallArgs)
  1169.       break;
  1170.  
  1171.     if(ap.CallArgs >= MAXREG-2)
  1172.     {
  1173.       DoError(ERR_TO_MUCH_ARGUMENTS, linenum); break;
  1174.     }
  1175.  
  1176.     in.pos = SkipName(oldptr);
  1177.     if(*in.pos == '*')
  1178.       ++in.pos;
  1179.     if(!(len = in.pos-oldptr))
  1180.     {
  1181.       DoError(ERR_EXPECTED_ARGUMENT_NAME, linenum);
  1182.       break;
  1183.     }
  1184.  
  1185.     ap.Args[ap.CallArgs++].ArgName = oldptr;
  1186.     oldptr = in.pos;
  1187.  
  1188.     in.pos = SkipBlanks(in.pos);
  1189.     if(*in.pos != ',' && *in.pos != '/' && *in.pos != ')')
  1190.     {
  1191.       DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
  1192.       break;
  1193.     }
  1194.     if(*in.pos != ')') /* create c string ending */
  1195.       *oldptr = '\0';
  1196.       }
  1197.       while(*in.pos != ')');
  1198.       if(*in.pos != ')')
  1199.       {
  1200.     while(*(in.pos++))
  1201.       ++in.pos;
  1202.     continue;
  1203.       }
  1204.       else
  1205.     *oldptr = '\0'; /* create c string ending for last argument */
  1206.  
  1207.       if(*(in.pos = SkipBlanks(in.pos+1)) != '(')
  1208.       {
  1209.     DoError(ERR_EXPECTED_OPEN_BRACKET, linenum);
  1210.     ++in.pos;
  1211.     continue;
  1212.       }
  1213.  
  1214.       do
  1215.       {
  1216.     ULONG i;
  1217.  
  1218.     oldptr = in.pos = SkipBlanks(in.pos + 1);
  1219.  
  1220.     if(*in.pos == ')' && !ap.NumArgs)
  1221.       break;
  1222.  
  1223.     in.pos = SkipName(oldptr);
  1224.     len = in.pos-oldptr;
  1225.  
  1226.     for(i = 0; i < MAXREG; ++i)
  1227.           if(!strnicmp(RegNames[i], oldptr, len))
  1228.             break;
  1229.  
  1230.     if(i == MAXREG)
  1231.     {
  1232.       DoError(ERR_EXPECTED_REGISTER_NAME, linenum);
  1233.       break;
  1234.     }
  1235.     else if(i == REG_A6)
  1236.       ap.Flags |= AMIPRAGFLAG_A6USE;
  1237.     if(i == REG_A7)
  1238.     {
  1239.       DoError(ERR_A7_NOT_ALLOWED, linenum);
  1240.       break;
  1241.     }
  1242.     else if(i >= REG_FP0)
  1243.       ap.Flags |= AMIPRAGFLAG_FLOATARG;
  1244.  
  1245.     ap.Args[ap.NumArgs].ArgReg = i;
  1246.  
  1247.     if(ap.CallArgs < ap.NumArgs)    /* get name when no given */
  1248.       ap.Args[ap.NumArgs].ArgName = RegNames[i];
  1249.  
  1250.     for(i = 0; i < ap.NumArgs; i++)
  1251.     {
  1252.       if(ap.Args[ap.NumArgs].ArgReg == ap.Args[i].ArgReg)
  1253.       {
  1254.         DoError(ERR_REGISTER_USED_TWICE, linenum);
  1255.         break;
  1256.       }
  1257.     }
  1258.     if(i < ap.NumArgs)
  1259.       break;
  1260.  
  1261.     ++ap.NumArgs;
  1262.  
  1263.     in.pos = SkipBlanks(in.pos);
  1264.     if(*in.pos != ',' && *in.pos != '/' && *in.pos != ')')
  1265.     {
  1266.       DoError(ERR_EXPECTED_CLOSE_BRACKET, linenum);
  1267.       break;
  1268.     }
  1269.       }
  1270.       while(*in.pos != ')');
  1271.  
  1272.       ap.Bias = bias;
  1273.       ap.Line = linenum;
  1274.       bias += BIAS_OFFSET;
  1275.  
  1276.       if(*in.pos != ')')
  1277.       {
  1278.     while(*(in.pos++))
  1279.       ++in.pos;
  1280.     continue;
  1281.       }
  1282.       else
  1283.     ++in.pos;
  1284.  
  1285.       if(Flags & FLAG_STORMFD)
  1286.       {
  1287.     if(!strcmp(ap.Args[ap.CallArgs-1].ArgName, "tags"))
  1288.     {
  1289.       ap.TagName = ap.FuncName;
  1290.       ap.FuncName = 0;
  1291.       ++tagfuncs;
  1292. #ifdef DEBUG_OLD
  1293.       VPrintf("ScanFDFile: StormFD mode, tag func: %s\n", &ap.TagName);
  1294. #endif
  1295.     }
  1296. #ifdef DEBUG_OLD
  1297.     else
  1298.     {
  1299.       STRPTR a[2];
  1300.       a[0] = ap.FuncName;
  1301.       a[1] = ap.Args[ap.CallArgs-1].ArgName;
  1302.       VPrintf("ScanFDFile: StormFD mode, normal func: %s(..., %s)\n", &a);
  1303.     }
  1304. #endif
  1305.       }
  1306.       else if((_public || (Flags & FLAG_PRIVATE)) && !MakeTagFunction(&ap))
  1307.     return 0;
  1308.       else    /* check the alias names */
  1309.       {
  1310.         ULONG i = 0;
  1311.  
  1312.         while(Pragma_AliasNames[i].FunctionName &&
  1313.         strcmp(ap.FuncName, Pragma_AliasNames[i].FunctionName))
  1314.           ++i;
  1315.  
  1316.         if(Pragma_AliasNames[i].FunctionName)
  1317.           ap.AliasName = &Pragma_AliasNames[i];
  1318.       }
  1319.  
  1320.       if(ap.CallArgs != ap.NumArgs)
  1321.     ap.Flags |= AMIPRAGFLAG_ARGCOUNT;
  1322.  
  1323.       if(bias == -1)
  1324.       {
  1325.     DoError(ERR_ASSUMING_BIAS_OF_30, linenum);
  1326.     bias = 30;
  1327.       }
  1328.  
  1329.       if(_public)
  1330.         ap.Flags |= AMIPRAGFLAG_PUBLIC;
  1331.  
  1332.       if((Flags & FLAG_NOFPU) && (ap.Flags & AMIPRAGFLAG_FLOATARG))
  1333.     DoError(ERR_FLOATARG_NOT_ALLOWED, linenum);
  1334.       else if((ap.Flags & AMIPRAGFLAG_FLOATARG) || !(Flags & FLAG_FPUONLY))
  1335.       { /* skip all without FPU when FPUONLY */
  1336.     struct AmiPragma *d;
  1337.     if(!(d = (struct AmiPragma *) NewItem(&AmiPragma)))
  1338.       return 0;
  1339.     CopyMem(&ap, d, sizeof(struct AmiPragma));
  1340.     AddItem(&AmiPragma, (struct ShortList *) d);
  1341.     if(!SpecialFuncs())
  1342.       return 0;
  1343.       }
  1344.     }
  1345.  
  1346.     in.pos = SkipBlanks(in.pos);
  1347.     if(*in.pos)
  1348.       DoError(ERR_EXTRA_CHARACTERS, linenum);
  1349.     ++in.pos; /* skip '\0' */
  1350.   }
  1351.  
  1352.   if(CTRL_C)
  1353.   {
  1354.     DoError(ERR_USER_ABORT, 0);
  1355.     return 0;
  1356.   }
  1357.  
  1358.   if(bias)
  1359.     DoError(ERR_MISSING_END, 0);
  1360.  
  1361.   return 1;
  1362. }
  1363.  
  1364. LONG ScanTypes(STRPTR ptr, ULONG size)
  1365. {
  1366.   struct CPP_ExternNames *a = 0, *b = 0;
  1367.   STRPTR endptr = ptr+size;
  1368.   LONG line;
  1369.  
  1370.   for(line = 1; ptr < endptr; ++line)
  1371.   {
  1372.     struct CPP_ExternNames *n;
  1373.  
  1374.     if(*ptr == '*') /* skip comments */
  1375.     {
  1376.       while(ptr < endptr && *(ptr++) != '\n')
  1377.         ;
  1378.     }
  1379.     else if((n = (struct CPP_ExternNames *)
  1380.       AllocListMem(sizeof(struct CPP_ExternNames))))
  1381.     {
  1382.       STRPTR wptr;
  1383.  
  1384.       n->Type = ptr; /* store start */
  1385.  
  1386.       wptr = ptr;
  1387.       while(ptr < endptr && *ptr != ':' && *ptr != '\n')
  1388.       {
  1389.         if(*ptr == '\t' || *ptr == ' ')
  1390.         {
  1391.           *(wptr++) = ' ';
  1392.           ptr = SkipBlanks(ptr);
  1393.         }
  1394.         else
  1395.           *(wptr++) = *(ptr++);
  1396.       }
  1397.       if(*(ptr++) != ':')
  1398.         return line;
  1399.       if(*(wptr-1) == ' ')
  1400.         --wptr;
  1401.       *wptr = 0;
  1402.       
  1403.       if(!GetCPPType(&n->NameType, (ptr = SkipBlanks(ptr))))
  1404.         return line;
  1405. #ifdef DEBUG_OLD
  1406.   Printf("'%20s', slen %2ld, typelen %2ld, pntd %ld, type %lc, sn '%.3s'\n",
  1407.   n->Type, n->NameType.StructureLength, n->NameType.FullLength,
  1408.   n->NameType.PointerDepth, n->NameType.Type ? n->NameType.Type : 's',
  1409.   n->NameType.StructureName ? n->NameType.StructureName : "<e>");
  1410. #endif
  1411.       ptr = SkipBlanks(n->NameType.TypeStart+n->NameType.FullLength);
  1412.       if(*(ptr++) != '\n')
  1413.       {
  1414. #ifdef DEBUG_OLD
  1415.         Printf("%.30s\n", ptr);
  1416. #endif
  1417.         return line;
  1418.       }
  1419.  
  1420.       if(!a)
  1421.         b = n;
  1422.       else
  1423.         a->Next = n;
  1424.       a = n;
  1425.     }
  1426.     else
  1427.       return -1;
  1428.   }
  1429.   extnames = b; /* now store the list */
  1430.   return 0;
  1431. }
  1432.  
  1433. void FindHeader(void)
  1434. {
  1435.   STRPTR str = HEADER;
  1436.   ULONG mode = 0;
  1437.  
  1438.   do
  1439.   {
  1440.     if(!mode)
  1441.       HEADER = str;
  1442.  
  1443.     if(*str == '/')
  1444.     {
  1445.       ++str;
  1446.       if(*str == '*')
  1447.       {
  1448.     mode = 2; break;
  1449.       }
  1450.       else if(*str == '/')
  1451.     mode = 1;
  1452.     }
  1453.     else if(*str == '*' || *str == ';')
  1454.       mode = 1;
  1455.     else if(mode)
  1456.       break;
  1457.     while(*str && *(str++) != '\n')
  1458.       ;
  1459.   } while(*str);
  1460.  
  1461.   if(mode == 2)
  1462.   {
  1463.     while(*str && (*(str-1) != '*' || *str != '/'))
  1464.       ++str;
  1465.     while(*str && *(str++) != '\n')
  1466.       ;
  1467.   }
  1468.  
  1469.   if(mode)
  1470.     headersize = str-HEADER;
  1471.   else
  1472.   {
  1473.     HEADER = 0; headersize = 0;
  1474.   }
  1475. }
  1476.  
  1477. /* returns decrement data in bits 0-15 and increment data in bits 16-31 */
  1478. ULONG GetRegisterData(struct AmiPragma *ap)
  1479. {
  1480. /* usage of result:
  1481.     48E7 <lower word>    MOVEM.L <registers>,-(A7) ; D0 is bit 15
  1482.     4CDF <upper word>    MOVEM.L (A7)+,<registers> ; D0 is bit 0
  1483. */
  1484.   register ULONG i, data = 0, reg;
  1485.  
  1486.   for(i = 0; i < ap->NumArgs; ++i)
  1487.   {
  1488.     if((reg = ap->Args[i].ArgReg) <= REG_FP0)
  1489.     {
  1490.       if(reg >= 10 || (reg >= 2 &&  reg <= 7)) /* A2-A7 and D2-D7 */
  1491.         data |= (1 << (reg + 16)) + (1 << (15 - reg));
  1492.     }
  1493.   }
  1494.   if(data)    /* set A6 only when other register used */
  1495.     data |= 0x40000002;
  1496.   return data;
  1497. }
  1498.  
  1499. UWORD GetFRegisterData(struct AmiPragma *ap)
  1500. {
  1501. /* usage of result:
  1502.     F227 <upper byte>    FMOVEM.X <registers>,-(A7) ; FP0 is bit 0
  1503.     F21F <lower byte>    FMOVEM.X (A7)+,<registers> ; FP0 is bit 7
  1504. */
  1505.   register ULONG i, reg;
  1506.   register UWORD data = 0;
  1507.  
  1508.   for(i = 0; i < ap->NumArgs; ++i)
  1509.   {
  1510.     if((reg = ap->Args[i].ArgReg) >= REG_FP2)
  1511.     {
  1512.       reg -= REG_FP0;
  1513.       data |= (1 << (reg + 8)) + (1 << (7 - reg));
  1514.     }
  1515.   }
  1516.   return data;
  1517. }
  1518.  
  1519. ASM(static void) __saveds xdefputfunc(REG(d0, UBYTE data), REG(a3, STRPTR *a))
  1520. {
  1521. #ifdef __MAXON__
  1522.   GetBaseReg();
  1523. #endif
  1524.   *((*a)++) = data;
  1525. }
  1526.  
  1527. ULONG OutputXDEF(STRPTR format, ...)
  1528. {
  1529.   UBYTE b[150];
  1530.   STRPTR c = b + 4;
  1531.   UWORD i;
  1532.  
  1533.   memset(b, 0, 150);
  1534.   RawDoFmt(format, (APTR) ((ULONG)&format+sizeof(STRPTR)),
  1535.   (void(*)()) xdefputfunc, &c);
  1536.   /* c now holds pointer to end */
  1537.   i = (c-(b+4)+2)>>2;
  1538.   *((ULONG *) b) = 0x01000000 + i;
  1539.  
  1540.   return DoOutputDirect(b, (i+2)<<2);
  1541. }
  1542.  
  1543. UWORD *AsmStackCopy(UWORD *data, struct AmiPragma *ap, ULONG flags,
  1544. ULONG ofs)
  1545. {
  1546.   ULONG j, k;
  1547.  
  1548.   if(Flags & FLAG_PASCAL)
  1549.   {
  1550.     k = ap->NumArgs;
  1551.  
  1552.     while(k)
  1553.     {
  1554.       if(ap->Args[k-1].ArgReg >= REG_FP0)
  1555.       {
  1556.         struct ClibData *cd; 
  1557.  
  1558.     cd = GetClibFunc(ap->FuncName, ap, flags);
  1559.         *(data++) = 0xF22F;        /* FMOVE.? offs(A7),FPx */
  1560.  
  1561.         if(cd && IsCPPType(&cd->Args[k-1], CPP_TYPE_DOUBLE))
  1562.         {
  1563.           *(data++) = 0x5400 + ((ap->Args[--k].ArgReg-REG_FP0)<<7);
  1564.           *(data++) = ofs<<2; /* one double needs two longs */
  1565.           ofs += 2;
  1566.         }
  1567.         else
  1568.         {
  1569.           if(!cd || !IsCPPType(&cd->Args[k-1], CPP_TYPE_FLOAT))
  1570.             DoError(ERR_LONG_DOUBLE, ap->Line);
  1571.           *(data++) = 0x4400 + ((ap->Args[--k].ArgReg-REG_FP0)<<7);
  1572.           *(data++) = (ofs++) << 2;
  1573.         }
  1574.       }
  1575.       else if((k >= 2) && (ap->Args[k-1].ArgReg < ap->Args[k-2].ArgReg))
  1576.       {
  1577.         *(data++) = 0x4CEF;        /* MOVEM.L offs(A7),xxx */
  1578.         *(data++) = 0;
  1579.         *(data++) = ofs << 2;        /* store start offset */
  1580.         do
  1581.         {
  1582.           j = ap->Args[--k].ArgReg;
  1583.  
  1584.       ++ofs;
  1585.           *(data-2) |= 1 << j;
  1586.         } while(k && j < ap->Args[k-1].ArgReg);
  1587.       }
  1588.       else
  1589.       {
  1590.         *data = 0x202F;            /* MOVE.L offs(A7),xxx */
  1591.  
  1592.         if((j = ap->Args[--k].ArgReg) > 7)
  1593.         {
  1594.           *data |= (1<<6); j -= 8;    /* set MOVEA bit */
  1595.         }
  1596.         *(data++) |= j << 9;        /* set destination register */
  1597.         *(data++) = (ofs++) << 2;
  1598.       }
  1599.     }
  1600.   }
  1601.   else
  1602.   {
  1603.     ULONG i = 0;
  1604.  
  1605.     k = ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0);
  1606.  
  1607.     while(i < k)
  1608.     {
  1609.       if(ap->Args[i].ArgReg >= REG_FP0)
  1610.       {
  1611.         struct ClibData *cd; 
  1612.  
  1613.     cd = GetClibFunc(ap->FuncName, ap, flags);
  1614.         *(data++) = 0xF22F;        /* FMOVE.? offs(A7),FPx */
  1615.  
  1616.         if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_DOUBLE))
  1617.         {
  1618.           *(data++) = 0x5400 + ((ap->Args[i++].ArgReg-REG_FP0)<<7);
  1619.           *(data++) = ofs<<2; /* one double needs two longs */
  1620.           ofs += 2;
  1621.         }
  1622.         else
  1623.         {
  1624.           if(!cd || !IsCPPType(&cd->Args[k-1], CPP_TYPE_FLOAT))
  1625.             DoError(ERR_LONG_DOUBLE, ap->Line);
  1626.           *(data++) = 0x4400 + ((ap->Args[i++].ArgReg-REG_FP0)<<7);
  1627.           *(data++) = (ofs++) << 2;
  1628.         }
  1629.       }
  1630.       else if(((k - i) >= 2) && (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg))
  1631.       {
  1632.         *(data++) = 0x4CEF;        /* MOVEM.L offs(A7),xxx */
  1633.         *(data++) = 0;            /* Store MOVEM.L data later */
  1634.         *(data++) = ofs << 2;        /* store start offset */
  1635.         do
  1636.         {
  1637.           j = ap->Args[i++].ArgReg;
  1638.  
  1639.       ++ofs;
  1640.           *(data-2) |= 1 << j;
  1641.         } while(i < k && j < ap->Args[i].ArgReg);
  1642.       }
  1643.       else
  1644.       {
  1645.         *data = 0x202F;            /* MOVE.L offs(A7),xxx */
  1646.  
  1647.         if((j = ap->Args[i++].ArgReg) > 7)
  1648.         {
  1649.           *data |= (1<<6); j -= 8;    /* set MOVEA bit */
  1650.         }
  1651.         *(data++) |= j << 9;        /* set destination register */
  1652.         *(data++) = (ofs++) << 2;
  1653.       }
  1654.     }
  1655.  
  1656.     if(i < ap->NumArgs)
  1657.     {
  1658.       if((j = ap->Args[i].ArgReg) > 7)
  1659.       {
  1660.         *(data++) = 0x41EF | ((j-8) << 9);    /* LEA xxx(A7),Ax */
  1661.         *(data++) = ofs << 2;
  1662.       }
  1663.       else
  1664.       {
  1665.         *(data++) = 0x200F | (j << 9);        /* MOVE.L A7,Dx */
  1666.         if(ofs == 2)
  1667.           *(data++) = 0x5080 | j;         /* ADDQ.L #8,Dx */
  1668.         else
  1669.         {
  1670.       *(data++) = 0xD0BC | (j<<9);        /* ADD.L #x,Dx */
  1671.       *(data++) = 0;
  1672.       *(data++) = ofs << 2;
  1673.         }
  1674.       }
  1675.     }
  1676.   }
  1677.  
  1678.   return data;
  1679. }
  1680. /* ------------------------------------------------------------------ */
  1681.  
  1682. void DoError(UBYTE errnum, ULONG line, ...)
  1683. {
  1684.   if(Flags & FLAG_DIDERROR)
  1685.     return;
  1686.  
  1687.   if(!Errors[errnum].Type)
  1688.     Flags |= FLAG_DIDERROR;
  1689.  
  1690.   Printf((line ? "%s %ld in line %ld: " : "%s %ld : "),
  1691.   Errors[errnum].Type ? "Warning" : "Error", errnum, line);
  1692.   VPrintf(Errors[errnum].Error, (((STRPTR) &line) + sizeof(ULONG)));
  1693.   PutStr("\n");
  1694.   if(line && Errors[errnum].Skip)
  1695.   {
  1696.     while(*in.pos)
  1697.       ++in.pos;
  1698.   }
  1699. }
  1700.  
  1701. ULONG Out(ULONG size)
  1702. {
  1703.   ULONG i = out.pos-out.buf;
  1704.  
  1705.   if(i && out.size - i <= size)
  1706.   {
  1707.     if(Write(out.file, out.buf, i) != i)
  1708.     {
  1709.       Output_Error = 0;
  1710.       return 0;
  1711.     }
  1712.     out.pos = out.buf;
  1713.   }
  1714.   return out.size;
  1715. }
  1716.  
  1717. ASM(static void) __saveds putfunc(REG(d0, UBYTE data), REG(a3, LONG *a))
  1718. {
  1719. #ifdef __MAXON__
  1720.   GetBaseReg();
  1721. #endif
  1722.  
  1723.   if(data)
  1724.   {
  1725.     if(!*a)
  1726.       *a = Out(1);
  1727.     if((*a)-- > 0)
  1728.       *(out.pos++) = data;
  1729.   }
  1730. }
  1731.  
  1732. ULONG DoOutput(STRPTR format, ...)
  1733. {
  1734.   LONG a = out.buf+out.size-out.pos;
  1735.  
  1736.   if(!Output_Error)
  1737.     return 0;
  1738.  
  1739.   RawDoFmt(format, (APTR) ((ULONG)&format+sizeof(STRPTR)),
  1740.   (void(*)()) putfunc, &a);
  1741.  
  1742.   if(a < 0)
  1743.     return 0;
  1744.   return 1;
  1745. }
  1746.  
  1747. ULONG DoOutputDirect(APTR data, ULONG size)
  1748. {
  1749.   if(!Output_Error || !Out(size))
  1750.     return 0;
  1751.   CopyMem(data, out.pos, size);
  1752.   out.pos += size;
  1753.   return 1;
  1754. }
  1755.  
  1756. /* ------------------------------------------------------------------ */
  1757.  
  1758. struct ShortList *NewItem(struct ShortListRoot *list)
  1759. {
  1760.   struct ShortList *item;
  1761.   if(!list || !list->Size)
  1762.     return 0;
  1763.   if(!(item = (struct ShortList *) AllocListMem(list->Size)))
  1764.     return 0;
  1765.   return item;
  1766. }
  1767.  
  1768. struct ShortList *RemoveItem(struct ShortListRoot *list, struct ShortList *item)
  1769. {
  1770.   struct ShortList *n = list->First;
  1771.  
  1772.   if(n == item)
  1773.     list->First = item->Next;
  1774.   else
  1775.   {
  1776.     while(n && n->Next != item)
  1777.       n = n->Next;
  1778.     if(!n)
  1779.       return 0;
  1780.     if(!(n->Next = item->Next))
  1781.       list->Last = n;
  1782.   }
  1783.   item->Next = 0;
  1784.   return item;
  1785. }
  1786.  
  1787. void AddItem(struct ShortListRoot *list, struct ShortList *item)
  1788. {
  1789.   if(!list->First)
  1790.     list->First = list->Last = item;
  1791.   else
  1792.   {
  1793.     list->Last->Next = item;
  1794.     list->Last = item;
  1795.   }
  1796. }
  1797.  
  1798. /* ------------------------------------------------------------------ */
  1799.  
  1800. ULONG FuncAMICALL(struct AmiPragma *ap, ULONG flags, STRPTR name)
  1801. {
  1802.   ULONG i;
  1803.  
  1804.   if(ap->Flags & AMIPRAGFLAG_ARGCOUNT)
  1805.   {
  1806.     if(!(ap->Flags & AMIPRAGFLAG_DIDWARN))
  1807.     {
  1808.       DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER, ap->Line);
  1809.       ap->Flags |= AMIPRAGFLAG_DIDWARN;
  1810.     }
  1811.     return 1;
  1812.   }
  1813.  
  1814.   Flags |= FLAG_DONE; /* We did something */
  1815.  
  1816.   DoOutput("#pragma %s(%s,0x%03lx,%s("/*))*/, flags & FUNCFLAG_TAG ?
  1817.   "tagcall" : "amicall", BaseName, ap->Bias, name);
  1818.  
  1819.   for(i = 0; i < ap->NumArgs; ++i)
  1820.   {
  1821.     DoOutput(RegNames[ap->Args[i].ArgReg]);
  1822.     if(i+1 < ap->NumArgs)
  1823.       DoOutput(",");
  1824.   }
  1825.  
  1826.   return DoOutput(/*((*/"))\n");
  1827. }
  1828.  
  1829. ULONG FuncLIBCALL(struct AmiPragma *ap, ULONG flags, STRPTR name)
  1830. {
  1831.   LONG i;
  1832.  
  1833.   if(ap->Flags & AMIPRAGFLAG_ARGCOUNT)
  1834.   {
  1835.     if(!(ap->Flags & AMIPRAGFLAG_DIDWARN))
  1836.     {
  1837.       DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER, ap->Line);
  1838.       ap->Flags |= AMIPRAGFLAG_DIDWARN;
  1839.     }
  1840.     return 1;
  1841.   }
  1842.  
  1843.   Flags |= FLAG_DONE; /* We did something */
  1844.  
  1845.   if(ap->Flags & AMIPRAGFLAG_FLOATARG)
  1846.   {
  1847.     DoOutput("#pragma flibcall %s %-20s %03lx ", BaseName, name, ap->Bias);
  1848.     for(i = ap->NumArgs-1; i >= 0; --i)
  1849.       DoOutput("%02lx", ap->Args[i].ArgReg);
  1850.  
  1851.     return DoOutput("00%02lx\n", ap->NumArgs);
  1852.   }
  1853.  
  1854.   if((Flags & FLAG_SYSCALL) && !strcmp(BaseName,"SysBase") &&
  1855.   (flags & FUNCFLAG_NORMAL))
  1856.     DoOutput("#pragma  syscall %-20s %03lx ", name, ap->Bias);
  1857.   else
  1858.     DoOutput("#pragma  %s %s %-20s %03lx ", (flags & FUNCFLAG_TAG) ?
  1859.     "tagcall" : "libcall", BaseName, name, ap->Bias);
  1860.  
  1861.   for(i = ap->NumArgs-1; i >= 0; --i)
  1862.     DoOutput("%lx", ap->Args[i].ArgReg);
  1863.  
  1864.   return DoOutput("0%lx\n", ap->NumArgs);
  1865. }
  1866.  
  1867. ULONG FuncAsmText(struct AmiPragma *ap, ULONG flags, STRPTR name)
  1868. {
  1869.   LONG i;
  1870.   ULONG registers;
  1871.   UWORD fregs;
  1872.   ULONG offset = 1;
  1873.   struct ClibData *cd;
  1874.  
  1875.   Flags |= FLAG_DONE; /* We did something */
  1876.  
  1877.   DoOutput("\n\tXDEF\t_%s\n_%s:\n",name, name);
  1878.   if(!(Flags & FLAG_PASCAL))
  1879.   {
  1880.     DoOutput("\n\tXDEF\t%s\n%s:\n",name, name);
  1881.     if(clibdata)
  1882.     {
  1883.       if(!ap->NumArgs)
  1884.         DoOutput("\tXDEF\t%s_\n%s_:\n",name, name);
  1885.       else if((cd = GetClibFunc(name, ap, flags)))
  1886.       {
  1887.         UBYTE txt[300];
  1888.         ULONG ret = 0;
  1889.  
  1890.         do
  1891.         {
  1892.       if((ret = CopyCPPType(txt, ret, cd, ap->Args)))
  1893.         DoOutput("\tXDEF\t%s__%s\n%s__%s:\n", name, txt, name, txt);
  1894.         } while(ret == 0xFFFFFFFF);
  1895.       }
  1896.     }
  1897.   }
  1898.  
  1899.   if((registers = GetRegisterData(ap) >> 16))
  1900.   {
  1901.     UWORD l = registers;
  1902.  
  1903.     DoOutput("\tMOVEM.L\t");
  1904.  
  1905.     for(i = 0; i <= 15; ++i)
  1906.     {
  1907.       if(l & (1 << i))
  1908.       {
  1909.     ++offset;
  1910.     l ^= 1 << i;
  1911.     DoOutput(RegNamesUpper[i]);
  1912.     if(l)
  1913.       DoOutput("/");
  1914.       }
  1915.     }
  1916.     DoOutput(",-(A7)\n");
  1917.   }
  1918.   else
  1919.   {
  1920.     DoOutput("\tMOVE.L\tA6,-(A7)\n"); ++offset;
  1921.   }
  1922.  
  1923.   if((fregs = GetFRegisterData(ap) >> 8))
  1924.   {
  1925.     UBYTE l = fregs;
  1926.  
  1927.     DoOutput("\tFMOVEM.X\t");
  1928.  
  1929.     for(i = 0; i <= 7; ++i)
  1930.     {
  1931.       if(l & (1 << i))
  1932.       {
  1933.     offset += 3;
  1934.     l ^= 1 << i;
  1935.     DoOutput(RegNamesUpper[REG_FP0 + i]);
  1936.     if(l)
  1937.       DoOutput("/");
  1938.       }
  1939.     }
  1940.     DoOutput(",-(A7)\n");
  1941.   }
  1942.  
  1943.   if(Flags & FLAG_SMALLDATA)
  1944.     DoOutput("\tMOVE.L\t_%s(A4),A6\n", BaseName);
  1945.   else
  1946.     DoOutput("\tMOVE.L\t_%s,A6\n", BaseName);
  1947.  
  1948.   if(!(Flags & FLAG_PASCAL))
  1949.   {
  1950.     ULONG k;
  1951.  
  1952.     k = ap->NumArgs - ((flags & FUNCFLAG_TAG) ? 1 : 0);
  1953.  
  1954.     for(i = 0; i < k;)
  1955.     {
  1956.       if(ap->Args[i].ArgReg >= REG_FP0)
  1957.       {
  1958.         ULONG t;
  1959.     struct ClibData *cd;
  1960.  
  1961.     cd = GetClibFunc(name, ap, flags);
  1962.     if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_DOUBLE))
  1963.       t = CPP_TYPE_DOUBLE;
  1964.     else if(cd && IsCPPType(&cd->Args[i], CPP_TYPE_FLOAT))
  1965.       t = CPP_TYPE_FLOAT;
  1966.         else
  1967.         {
  1968.           DoError(ERR_LONG_DOUBLE, ap->Line);
  1969.       t = CPP_TYPE_FLOAT;
  1970.     }
  1971.  
  1972.     DoOutput("\tFMOVE.%lc\t%02ld(A7),%s\n", t == CPP_TYPE_DOUBLE ? 'D' : 'S',
  1973.     offset<<2, RegNamesUpper[ap->Args[i++].ArgReg]);
  1974.     if(t == CPP_TYPE_DOUBLE)
  1975.       ++offset;
  1976.         ++offset;
  1977.       }
  1978.       else if(((k - i) >= 2) && (ap->Args[i].ArgReg < ap->Args[i+1].ArgReg))
  1979.       {
  1980.         DoOutput("\tMOVEM.L\t%02ld(A7),%s", (offset++)<<2,
  1981.         RegNamesUpper[ap->Args[i++].ArgReg]);
  1982.  
  1983.         do
  1984.         {
  1985.       DoOutput("/%s", RegNamesUpper[ap->Args[i++].ArgReg]);
  1986.       ++offset;
  1987.         } while((i < k) && (ap->Args[i-1].ArgReg < ap->Args[i].ArgReg));
  1988.     DoOutput("\n");
  1989.       }
  1990.       else
  1991.         DoOutput("\tMOVE.L\t%02ld(A7),%s\n", (offset++)<<2,
  1992.         RegNamesUpper[ap->Args[i++].ArgReg]);
  1993.     }
  1994.  
  1995.     if(i < ap->NumArgs)
  1996.     {
  1997.       if(ap->Args[i].ArgReg > 7)
  1998.     DoOutput("\tLEA\t%02ld(A7),%s\n", offset<<2,
  1999.     RegNamesUpper[ap->Args[i].ArgReg]);
  2000.       else
  2001.     DoOutput("\tMOVE.L\tA7,%s\n\tADD%s.L\t#%02ld,%s\n",
  2002.     RegNamesUpper[ap->Args[i].ArgReg], (offset <= 2 ? "Q" : ""),
  2003.     offset<<2, RegNamesUpper[ap->Args[i].ArgReg]);
  2004.     }
  2005.   }
  2006.   else
  2007.   {
  2008.     i = ap->NumArgs;
  2009.  
  2010.     while(i)
  2011.     {
  2012.       if(ap->Args[i-1].ArgReg >= REG_FP0)
  2013.       {
  2014.         ULONG t;
  2015.     struct ClibData *cd;
  2016.  
  2017.     cd = GetClibFunc(name, ap, flags);
  2018.  
  2019.     if(cd && IsCPPType(&cd->Args[i-1], CPP_TYPE_DOUBLE))
  2020.       t = CPP_TYPE_DOUBLE;
  2021.     else if(cd && IsCPPType(&cd->Args[i-1], CPP_TYPE_FLOAT))
  2022.       t = CPP_TYPE_FLOAT;
  2023.         else
  2024.         {
  2025.           DoError(ERR_LONG_DOUBLE, ap->Line);
  2026.       t = CPP_TYPE_FLOAT;
  2027.     }
  2028.  
  2029.     DoOutput("\tFMOVE.%lc\t%02ld(A7),%s\n", t == CPP_TYPE_DOUBLE ? 'D' : 'S',
  2030.     offset<<2, RegNamesUpper[ap->Args[--i].ArgReg]);
  2031.     if(t == CPP_TYPE_DOUBLE)
  2032.       ++offset;
  2033.         ++offset;
  2034.       }
  2035.       else if((i >= 2) && (ap->Args[i-1].ArgReg < ap->Args[i-2].ArgReg))
  2036.       {
  2037.         DoOutput("\tMOVEM.L\t%02ld(A7),%s", (offset++)<<2,
  2038.         RegNamesUpper[ap->Args[--i].ArgReg]);
  2039.  
  2040.         do
  2041.         {
  2042.       DoOutput("/%s", RegNamesUpper[ap->Args[--i].ArgReg]);
  2043.       ++offset;
  2044.         } while(i && (ap->Args[i].ArgReg < ap->Args[i-1].ArgReg));
  2045.     DoOutput("\n");
  2046.       }
  2047.       else
  2048.         DoOutput("\tMOVE.L\t%02ld(A7),%s\n", (offset++)<<2,
  2049.         RegNamesUpper[ap->Args[--i].ArgReg]);
  2050.     }
  2051.   }
  2052.  
  2053.   DoOutput("\tJSR\t-%03ld(A6)\n",ap->Bias);
  2054.  
  2055.   if(fregs)
  2056.   {
  2057.     DoOutput("\tFMOVEM.X\t(A7)+,");
  2058.  
  2059.     for(i = 0; i <= 7; ++i)
  2060.     {
  2061.       if(fregs & (1 << i))
  2062.       {
  2063.     fregs ^= 1 << i;
  2064.     DoOutput(RegNamesUpper[REG_FP0 + i]);
  2065.     if(fregs)
  2066.       DoOutput("/");
  2067.       }
  2068.     }
  2069.     DoOutput("\n");
  2070.   }
  2071.  
  2072.   if(registers)
  2073.   {
  2074.     DoOutput("\tMOVEM.L\t(A7)+,");
  2075.  
  2076.     for(i = 0; i <= 15; ++i)
  2077.     {
  2078.       if(registers & (1 << i))
  2079.       {
  2080.     registers ^= 1 << i;
  2081.     DoOutput(RegNamesUpper[i]);
  2082.     if(registers)
  2083.       DoOutput("/");
  2084.       }
  2085.     }
  2086.     DoOutput("\n");
  2087.   }
  2088.   else
  2089.     DoOutput("\tMOVE.L\t(A7)+,A6\n");
  2090.  
  2091.   return DoOutput("\tRTS\n");
  2092. }
  2093.  
  2094. ULONG FuncAsmCode(struct AmiPragma *ap, ULONG flags, STRPTR name)
  2095. {
  2096.   ULONG registers, a[5], offset = 1, pos = 4, baseref;
  2097.   LONG i = strlen(ShortBaseNameUpper);
  2098.   UWORD data[100]; /* 200 byte data field */
  2099.   UWORD fregs;
  2100.  
  2101.   Flags |= FLAG_DONE; /* We did something */
  2102.  
  2103.   registers = GetRegisterData(ap);
  2104.  
  2105.   fregs = GetFRegisterData(ap);
  2106.  
  2107.   a[0] = HUNK_UNIT; a[1] = 0; a[2] = HUNK_NAME;
  2108.   a[3] = (i + 6 + 3)>>2;
  2109.  
  2110.   DoOutputDirect(a, 16);
  2111.   DoOutputDirect(ShortBaseNameUpper, i);
  2112.   DoOutputDirect("_STUBS\0\0\0", (a[3]<<2)-i);
  2113.  
  2114.   data[0] = 0;
  2115.   data[1] = HUNK_CODE;
  2116.   data[2] = 0;
  2117.   /* data[3] is size */
  2118.  
  2119.   if(!registers)
  2120.   {
  2121.     data[pos++] = 0x2F0E;        /* MOVE.L A6,-(A7) */
  2122.     ++offset;                /* one long more on stack */
  2123.   }
  2124.   else
  2125.   {
  2126.     ULONG l;
  2127.     data[pos++] = 0x48E7;        /* MOVEM.L xxx,-(A7) */
  2128.     data[pos++] = registers;        /* storem MOVEM.L registers */
  2129.     for(l = (UWORD) registers; l; l >>= 1)
  2130.     {
  2131.       if(l & 1)
  2132.     ++offset;            /* get offset addition */
  2133.     }
  2134.   }
  2135.  
  2136.   if(fregs)
  2137.   {
  2138.     ULONG l;
  2139.     data[pos++] = 0xF227;        /* FMOVEM.X xxx,-(A7) */
  2140.     data[pos++] = 0xE000 + ((fregs>>8)&0xFF);
  2141.     for(l = (UBYTE) fregs; l; l >>= 1)
  2142.     {
  2143.       if(l & 1)
  2144.     offset+=3;            /* get offset addition */
  2145.     }
  2146.   }
  2147.  
  2148.   baseref = pos+1-4;        /* one word later (MOVE) - 2 header longs */
  2149.   if(Flags & FLAG_SMALLDATA)
  2150.   {
  2151.     data[pos++] = 0x2C6C;        /* MOVEA.L base(A4),A6 */
  2152.     data[pos++] = 0;            /* place for base reference */
  2153.   }
  2154.   else
  2155.   {
  2156.     data[pos++] = 0x2C79;        /* MOVEA.L base,A6 */
  2157.     data[pos++] = 0;            /* place for base reference */
  2158.     data[pos++] = 0;
  2159.   }
  2160.  
  2161.   pos = AsmStackCopy(data+pos, ap, flags, offset) - data;
  2162.  
  2163.   /* here comes the base reference */
  2164.   data[pos++] = 0x4EAE;            /* JSR xxx(A6) */
  2165.   data[pos++] = -ap->Bias;        /* JSR offset */
  2166.  
  2167.   if(fregs)
  2168.   {
  2169.     data[pos++] = 0xF21F;        /* FMOVEM.X (A7)+,xxx */
  2170.     data[pos++] = 0xD000 + (fregs&0xFF);
  2171.   }
  2172.  
  2173.   if(registers)
  2174.   {
  2175.     data[pos++] = 0x4CDF;        /* MOVEM.L (A7)+,xxx */
  2176.     data[pos++] = (registers >> 16);    /* store MOVEM.L registers */
  2177.   }
  2178.   else
  2179.     data[pos++] = 0x2C5F;        /* MOVE.L (A7)+,A6 */
  2180.   data[pos++] = 0x4E75;            /* RTS */
  2181.  
  2182.   if(pos & 1)
  2183.     data[pos++] = 0;            /* round to long */
  2184.  
  2185.   data[3] = (pos-4)>>1;            /* store hunk len */
  2186.   DoOutputDirect(data, pos<<1);
  2187.  
  2188.   a[0] = HUNK_EXT;
  2189.   a[1] = ((Flags & FLAG_SMALLDATA ? EXT_REF16 : EXT_REF32) << 24) +
  2190.          ((strlen(BaseName) + 1 + 3)>>2);
  2191.   a[2] = ('_' << 24);
  2192.  
  2193.   DoOutputDirect(a, 9);
  2194.   DoOutputDirect(BaseName, (((UWORD) a[1])<<2)-1);
  2195.  
  2196.   a[0] = 1; a[1] = baseref << 1;
  2197.   DoOutputDirect(a, 8);
  2198.  
  2199.   /* here come the XDEF name references */
  2200.   OutputXDEF("_%s", name);        /* C name */
  2201.  
  2202.   if(!(Flags & FLAG_PASCAL))
  2203.   {
  2204.     struct ClibData *cd;
  2205.     OutputXDEF("%s", name);        /* ASM name */
  2206.  
  2207.     if(clibdata)
  2208.     {
  2209.       if(!ap->NumArgs)
  2210.         OutputXDEF("%s_", name);        /* C++ name no parameters */
  2211.       else if((cd = GetClibFunc(name, ap, flags)))
  2212.       {
  2213.         ULONG ret = 0;
  2214.  
  2215.         do                /* C++ name with parameters */
  2216.         {
  2217.       if((ret = CopyCPPType((STRPTR) data, ret, cd, ap->Args)))
  2218.         OutputXDEF("%s__%s", name, (STRPTR) data);
  2219.         }   while(ret == 0xFFFFFFFF);
  2220.       }
  2221.     }
  2222.   }
  2223.  
  2224.   a[0] = 0; a[1] = HUNK_END;
  2225.  
  2226.   return DoOutputDirect(a, 8);
  2227. }
  2228.  
  2229. ULONG FuncCSTUBS(struct AmiPragma *ap, ULONG flags, STRPTR name)
  2230. {
  2231.   struct ClibData *f, *t;
  2232.   STRPTR ret = "return ";
  2233.   ULONG i;
  2234.  
  2235.   if(ap->Flags & AMIPRAGFLAG_ARGCOUNT)
  2236.   {
  2237.     DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER, ap->Line);
  2238.     return 1;
  2239.   }
  2240.  
  2241.   Flags |= FLAG_DONE; /* We did something */
  2242.  
  2243.   if(!(f = GetClibFunc(ap->FuncName, ap, 0)))
  2244.     return 1;
  2245.   t = GetClibFunc(name, ap, flags);
  2246.  
  2247.   if(IsCPPType(&f->ReturnType, CPP_TYPE_VOID))
  2248.     ret = 0;
  2249.  
  2250.   if(!OutClibType(&f->ReturnType, name) || !DoOutput("("/*)*/))
  2251.     return 0;
  2252.   for(i = 0; i < ap->NumArgs-1; i++)
  2253.   {
  2254.     if(!OutClibType(&f->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
  2255.       return 0;
  2256.   }
  2257.   if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
  2258.   {
  2259.     if(!OutClibType(&t->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
  2260.       return 0;
  2261.   }
  2262.   else if(ap->NumArgs == 1 && !DoOutput("ULONG tag, "))
  2263.     return 0;
  2264.  
  2265.   if(!DoOutput(/*(*/"...)\n{\n  %s%s("/*)*/, ret, ap->FuncName))
  2266.     return 0;
  2267.   for(i = 0; i < ap->NumArgs-1; i++)
  2268.   {
  2269.     if(!DoOutput("%s, ", ap->Args[i].ArgName))
  2270.       return 0;
  2271.   }
  2272.   if(!DoOutput("("/*)*/) || !OutClibType(&f->Args[ap->NumArgs-1],0))
  2273.     return 0;
  2274.  
  2275.   if(t && t->Args[i].Type != CPP_TYPE_VARARGS)
  2276.   {
  2277.     if(!DoOutput(/*((*/") &%s);\n}\n\n", ap->Args[ap->NumArgs-1].ArgName))
  2278.       return 0;
  2279.   }
  2280.   else if(ap->NumArgs == 1)
  2281.   {
  2282.     if(!DoOutput(/*((*/") &tag);\n}\n\n"))
  2283.       return 0;
  2284.   }
  2285.   else if (!DoOutput(/*(*/") ((ULONG) &%s + sizeof("/*))*/,
  2286.   ap->Args[ap->NumArgs-2].ArgName) || !OutClibType(&f->Args[ap->NumArgs-2],0)
  2287.   || !DoOutput(/*(((*/")));\n}\n\n"))
  2288.     return 0;
  2289.   return 1;
  2290. }
  2291.  
  2292. ULONG FuncLVOXDEF(struct AmiPragma *ap, ULONG flags, STRPTR name)
  2293. {
  2294.   Flags |= FLAG_DONE; /* We did something */
  2295.   return DoOutput("\t\tXDEF\t_LVO%s\n", name);
  2296. }
  2297.  
  2298. ULONG FuncLVO(struct AmiPragma *ap, ULONG flags, STRPTR name)
  2299. {
  2300.   Flags |= FLAG_DONE; /* We did something */
  2301.   return DoOutput("\n_LVO%-24s\tEQU\t-%ld", name, ap->Bias);
  2302. }
  2303.  
  2304. ULONG FuncLocCode(struct AmiPragma *ap, ULONG flags, STRPTR name)
  2305. {
  2306.   ULONG a[5];
  2307.   STRPTR str2 = Flags & FLAG_LOCALREG ? "rE" : "";
  2308.   LONG i = strlen(ShortBaseNameUpper);
  2309.   ULONG j;
  2310.   struct ClibData *cd;
  2311.  
  2312.   Flags |= FLAG_DONE; /* We did something */
  2313.  
  2314.   a[0] = HUNK_UNIT; a[1] = 0; a[2] = HUNK_NAME;
  2315.   a[3] = (i + 4 + 3)>>2;
  2316.  
  2317.   DoOutputDirect(a, 16);
  2318.   DoOutputDirect(ShortBaseNameUpper, i);
  2319.   DoOutputDirect("_LOC\0\0\0", (a[3]<<2)-i);
  2320.  
  2321.   if(Flags & FLAG_LOCALREG)
  2322.   {
  2323.     if((flags & FUNCFLAG_TAG))
  2324.     {
  2325.       j = ap->Args[ap->NumArgs-1].ArgReg;
  2326.       a[0] = HUNK_CODE; a[1] = 4;
  2327.       a[2] = 0x2F000000 + (j << 16);    /* MOVE <ea>,-(A7) */
  2328.  
  2329.       DoOutputDirect(a, 10);
  2330.  
  2331.       a[1] = 0x4EAE0000 + (UWORD) (- ap->Bias); /* JSR instruction */
  2332.       a[2] = 0x201F4E75;        /* MOVE (A7)+,<ea> */
  2333.       a[3] = 0;
  2334.       if(j > 7)
  2335.       {                 /* LEA x(A7),Ax */
  2336.     j -= 8;
  2337.     a[0] = 0x41EF0008 | (j << 25);
  2338.     a[2] += 0x400000;        /* set A flag */
  2339.       }
  2340.       else
  2341.       {                 /* MOVE.L A7,Dx  -- ADDQ.L #8,Dx */
  2342.     a[0] = 0x200F5080 | j | (j << 25);
  2343.       }
  2344.       a[2] += j << 25;
  2345.  
  2346.       DoOutputDirect(a, 14);
  2347.     }
  2348.     else
  2349.     {
  2350.       a[0] = HUNK_CODE; a[1] = 1;
  2351.       a[2] = 0x4EEE0000 + (UWORD) (- ap->Bias); /* JMP instruction */
  2352.       DoOutputDirect(a, 12);
  2353.     }
  2354.   }
  2355.   else
  2356.   {
  2357.     ULONG registers, offset = 1, pos = 4, l;
  2358.     UWORD data[100];                /* 200 byte data field */
  2359.  
  2360.     registers = GetRegisterData(ap);
  2361.  
  2362.     data[0] = 0;
  2363.     data[1] = HUNK_CODE;
  2364.     data[2] = 0;
  2365.     /* data[3] is size */
  2366.  
  2367.     if(!registers) /* happens only when !(ap->Flags & AMIPRAG_A6USE) */
  2368.     {
  2369.       data[pos++] = 0x2F0E;        /* MOVE.L A6,-(A7) */
  2370.       ++offset;                /* one long more on stack */
  2371.     }
  2372.     else
  2373.     {
  2374.       data[pos++] = 0x48E7;        /* MOVEM.L xxx,-(A7) */
  2375.       data[pos++] = registers;        /* storem MOVEM.L registers */
  2376.       for(l = (UWORD) registers; l; l >>= 1)
  2377.       {
  2378.         if(l & 1)
  2379.       ++offset;            /* get offset addition */
  2380.       }
  2381.     }
  2382.  
  2383.     if(!(ap->Flags & AMIPRAGFLAG_A6USE)) /* store library base in A6 */
  2384.     {
  2385.       data[pos++] = 0x2C6F;        /* MOVE.L ofs(A7),A6 */
  2386.       data[pos++] = (offset++) << 2;
  2387.     }
  2388.  
  2389.     pos = AsmStackCopy(data+pos, ap, flags, offset) - data;
  2390.  
  2391.     /* here comes the base reference */
  2392.     data[pos++] = 0x4EAE;        /* JSR xxx(A6) */
  2393.     data[pos++] = -ap->Bias;        /* JSR offset */
  2394.     if(registers)
  2395.     {
  2396.       data[pos++] = 0x4CDF;        /* MOVEM.L (A7)+,xxx */
  2397.       data[pos++] = (registers >> 16);    /* store MOVEM.L registers */
  2398.     }
  2399.     else
  2400.       data[pos++] = 0x2C5F;        /* MOVE.L (A7)+,A6 */
  2401.  
  2402.     data[pos++] = 0x4E75;        /* RTS */
  2403.  
  2404.     if(pos & 1)
  2405.       data[pos++] = 0;            /* round to long */
  2406.  
  2407.     data[3] = (pos-4)>>1;        /* store hunk len */
  2408.     DoOutputDirect(data, pos<<1);
  2409.   }
  2410.  
  2411.   a[0] = HUNK_EXT;
  2412.   DoOutputDirect(a,4);
  2413.  
  2414.   /* here come the XDEF name references */
  2415.  
  2416.   OutputXDEF("%s", name);    /* ASM names */
  2417.   OutputXDEF("LOC_%s", name);
  2418.  
  2419.   OutputXDEF("_%s", name);    /* C names */
  2420.   OutputXDEF("_LOC_%s", name);
  2421.  
  2422.   if(!ap->NumArgs && clibdata)
  2423.   {
  2424.     OutputXDEF("%s__%sP07Library", name, str2);    /* C++ names no parameters */
  2425.     OutputXDEF("LOC_%s__%sP07Library", name, str2);
  2426.   }
  2427.   else if((cd = GetClibFunc(name, ap, flags)))
  2428.   {
  2429.     UBYTE txt[100];
  2430.     ULONG ret = 0;
  2431.  
  2432.     do
  2433.     {
  2434.       if((ret = CopyCPPType(txt, ret, cd, ap->Args)))
  2435.       {                 /* C++ names with parameters */
  2436.         if(!(ap->Flags & AMIPRAGFLAG_A6USE))
  2437.         {
  2438.           OutputXDEF("%s__%sP07Library%s", name, str2, txt);
  2439.       OutputXDEF("LOC_%s__%sP07Library%s", name, str2, txt);
  2440.     }
  2441.     else
  2442.     {
  2443.           OutputXDEF("%s__%s", name, txt);
  2444.       OutputXDEF("LOC_%s__%s", name, txt);
  2445.     }
  2446.       }
  2447.     } while(ret == 0xFFFFFFFF);
  2448.   }
  2449.  
  2450.   a[0] = 0; a[1] = HUNK_END;
  2451.  
  2452.   return DoOutputDirect(a, 8);
  2453. }
  2454.  
  2455. ULONG FuncLocText(struct AmiPragma *ap, ULONG flags, STRPTR name)
  2456. {
  2457.   struct ClibData *cd;
  2458.   LONG i;
  2459.  
  2460.   if(ap->Flags & AMIPRAGFLAG_ARGCOUNT)
  2461.   {
  2462.     DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER, ap->Line);
  2463.     return 1;
  2464.   }
  2465.  
  2466.   Flags |= FLAG_DONE; /* We did something */
  2467.  
  2468.   if(!(cd = GetClibFunc(name, ap, flags)))
  2469.     return 1;
  2470.  
  2471.   OutClibType(&cd->ReturnType, 0);
  2472.   DoOutput(" LOC_%s("/*)*/, name);
  2473.   if(!(ap->Flags & AMIPRAGFLAG_A6USE))
  2474.   {
  2475.     if(Flags & FLAG_LOCALREG)
  2476.       DoOutput("register __a6 ");
  2477.     DoOutput("struct Library * libbase");
  2478.     if(ap->NumArgs)
  2479.       DoOutput(", ");
  2480.   }
  2481.  
  2482.   if(ap->NumArgs)
  2483.   {
  2484.     for(i = 0; i < ap->NumArgs-1; i++)
  2485.     {
  2486.       if(((Flags & FLAG_LOCALREG &&
  2487.       !DoOutput("register __%s ", RegNames[ap->Args[i].ArgReg]))) ||
  2488.       !OutClibType(&cd->Args[i], ap->Args[i].ArgName) || !DoOutput(", "))
  2489.     return 0;
  2490.     }
  2491.  
  2492.     if(flags & FUNCFLAG_NORMAL)
  2493.     {
  2494.       if(((Flags & FLAG_LOCALREG &&
  2495.       !DoOutput("register __%s ", RegNames[ap->Args[i].ArgReg]))) ||
  2496.       !OutClibType(&cd->Args[i], ap->Args[i].ArgName) ||
  2497.       !DoOutput(/*(*/");\n"))
  2498.         return 0;
  2499.       if(BaseName)
  2500.       {
  2501.         DoOutput("#define %s("/*)*/, name);
  2502.         for(i = 0; i < ap->NumArgs-1; ++i)
  2503.           DoOutput("%lc, ", (i+'a'));
  2504.         DoOutput(/*(*/"%lc) LOC_%s((struct Library *) %s, "/*)*/,(i+'a'),
  2505.         name, BaseName);
  2506.         for(i = 0; i < ap->NumArgs-1; ++i)
  2507.       DoOutput("%lc, ",(i+'a'));
  2508.         return DoOutput(/*(*/"%lc)\n\n",(i+'a'));
  2509.       }
  2510.     }
  2511.     else
  2512.       return DoOutput(/*(*/"...);\n");
  2513.   }
  2514.   else if(BaseName)
  2515.     return DoOutput(/*(*/");\n#define %s(a) LOC_%s((struct Library *) a)\n\n",
  2516.     name, name);
  2517.   else
  2518.     return DoOutput(/*(*/");\n");
  2519.   return 1;
  2520. }
  2521.  
  2522. ULONG FuncInline(struct AmiPragma *ap, ULONG flags, STRPTR name)
  2523. {
  2524.   ULONG noret = 0, a45 = 0, d7used = 0, i, j;
  2525.   LONG fp = -1;
  2526.   struct ClibData *cd;
  2527.  
  2528.   if(ap->Flags & AMIPRAGFLAG_ARGCOUNT)
  2529.   {
  2530.     DoError(ERR_ARGUMENTNUMBER_DIFFERS_FROM_REGISTERNUMBER, ap->Line);
  2531.     return 1;
  2532.   }
  2533.  
  2534.   Flags |= FLAG_DONE; /* We did something */
  2535.  
  2536.   if(flags & FUNCFLAG_ALIAS)
  2537.   {
  2538.     DoOutput("#define %s("/*)*/, name);
  2539.     for(i = 0; i < ap->NumArgs-1; ++i)
  2540.       DoOutput("%s, ", ap->Args[i].ArgName);
  2541.     DoOutput(/*(*/"%s) %s("/*)*/, ap->Args[i].ArgName, ap->FuncName);
  2542.     for(i = 0; i < ap->NumArgs-1; ++i)
  2543.       DoOutput("(%s), ", ap->Args[i].ArgName);
  2544.     return DoOutput(/*(*/"(%s))\n\n", ap->Args[i].ArgName);
  2545.   }
  2546.  
  2547.   if(!(cd = GetClibFunc(ap->FuncName, ap, flags)))
  2548.     return 1;
  2549.  
  2550.   if(IsCPPType(&cd->ReturnType, CPP_TYPE_VOID))
  2551.     noret = 1; /* this is a void function */
  2552.   for(i = 0; i < ap->NumArgs; ++i)
  2553.   {
  2554.     if(ap->Args[i].ArgReg == REG_A4 || ap->Args[i].ArgReg == REG_A5)
  2555.     {
  2556.       if(!a45)
  2557.     a45 = ap->Args[i].ArgReg; /* set flag */
  2558.       else /* Security check */
  2559.       {
  2560.     DoError(ERR_INLINE_A4_AND_A5, ap->Line); return 1; /* skip this entry */
  2561.       }
  2562.     }
  2563.     if(ap->Args[i].ArgReg == REG_D7) /* Used only when a45 != 0 */
  2564.       d7used = 1;
  2565.   }
  2566.   if(a45 && d7used) /* Security check */
  2567.   {
  2568.     DoError(ERR_INLINE_D7_AND_A45, ap->Line); return 1; /* skip this entry */
  2569.   }
  2570.  
  2571.   if((flags & FUNCFLAG_TAG))
  2572.   {
  2573.     if(!(Flags & FLAG_INLINESTUB)) /* no stubs */
  2574.     {
  2575.       DoOutput("#ifndef NO_INLINE_STDARG\n#define %s("/*)*/, name);
  2576.       for(i = 0; i < ap->NumArgs-1; ++i)
  2577.       {
  2578.         DoOutput("%s, ", ap->Args[i].ArgName);
  2579.       }
  2580.       DoOutput(/*(*/"tags...) \\\n\t({ULONG _tags[] = {tags}; %s("/*}))*/, ap->FuncName);
  2581.       for(i = 0; i < ap->NumArgs-1; ++i)
  2582.         DoOutput("(%s), ", ap->Args[i].ArgName);
  2583.       DoOutput("("/*)*/);
  2584.       OutClibType(&cd->Args[ap->NumArgs-1], 0);
  2585.       return DoOutput(/*({((*/")_tags);})\n#endif\n\n");
  2586.     }
  2587.     else
  2588.     {
  2589.       OutClibType(&cd->ReturnType, 0);
  2590.       DoOutput(" %s("/*)*/, name);
  2591.  
  2592.       for(i = 0; i < ap->NumArgs-1; ++i)
  2593.       {
  2594.         OutClibType(&cd->Args[i], ap->Args[i].ArgName);
  2595.         DoOutput(", ");
  2596.       }
  2597.  
  2598.       DoOutput(/*(*/"int tag, ...)\n{\n   "/*}*/);
  2599.       if(!noret)
  2600.     DoOutput("return ");
  2601.  
  2602.       DoOutput("%s("/*)*/, name);
  2603.       for(i = 0; i < ap->NumArgs-1; ++i)
  2604.         DoOutput("%s, ", ap->Args[i].ArgName);
  2605.  
  2606.       return DoOutput(/*{(*/"(struct TagItem *)&tag);\n}\n\n");
  2607.     }
  2608.   }
  2609.  
  2610.   if(Flags & FLAG_INLINENEW) /* new style */
  2611.   {
  2612.     STRPTR funcpar = "";
  2613.     DoOutput("#define %s("/*)*/, name);
  2614.  
  2615.     for(i = 0; i < cd->NumArgs; ++i)
  2616.     {
  2617.       if(cd->Args[i].Flags & CPP_FLAG_FUNCTION)
  2618.         funcpar = "FP";
  2619.     }
  2620.  
  2621.     if(ap->NumArgs)
  2622.     {
  2623.       for(i = 0; i < ap->NumArgs-1; ++i)
  2624.         DoOutput("%s, ", ap->Args[i].ArgName);
  2625.       DoOutput("%s", ap->Args[i].ArgName);
  2626.     }
  2627.     DoOutput(/*(*/") \\\n\tLP%ld%s%s%s%s(0x%lx, "/*)*/, ap->NumArgs,
  2628.     (noret ? "NR" : ""), (a45 ? RegNamesUpper[a45] : (STRPTR) ""),
  2629.     (BaseName ? "" : "UB"), funcpar, ap->Bias);
  2630.     if(!noret)
  2631.     {
  2632.       OutClibType(&cd->ReturnType, 0);
  2633.       DoOutput(", ");
  2634.     }
  2635.     DoOutput("%s, ", name);
  2636.  
  2637.     for(i = 0; i < ap->NumArgs; ++i)
  2638.     {
  2639.       j = ap->Args[i].ArgReg;
  2640.       if(a45 && (j == REG_A4 || j == REG_A5))
  2641.         j = REG_D7;
  2642.       if(cd->Args[i].Flags & CPP_FLAG_FUNCTION)
  2643.       {
  2644.         DoOutput("__fpt"); fp = i;
  2645.       }
  2646.       else
  2647.         OutClibType(&cd->Args[i], 0);
  2648.   
  2649.       DoOutput(", %s, %s%s", ap->Args[i].ArgName, RegNames[j],
  2650.       (i == ap->NumArgs-1 && !BaseName ? "" : ", "));
  2651.     }
  2652.  
  2653.     if(BaseName) /* was "##base" used? */
  2654.       DoOutput("\\\n\t, %s_BASE_NAME", ShortBaseNameUpper);
  2655.  
  2656.     if(fp >= 0)
  2657.     {
  2658.       DoOutput(", ");
  2659.       OutClibType(&cd->Args[fp], "__fpt");
  2660.     }
  2661.     return DoOutput(/*(*/")\n\n");
  2662.   }
  2663.  
  2664.   /* old mode or stubs mode */
  2665.  
  2666.   DoOutput("%s__inline ", Flags & FLAG_INLINESTUB ? "" : "extern ");
  2667.   OutClibType(&cd->ReturnType, 0);
  2668.   DoOutput("\n%s(%s"/*)*/, name, (BaseName ?
  2669.   (ap->NumArgs ? "BASE_PAR_DECL " : "BASE_PAR_DECL0") : ""));
  2670.  
  2671.   for(i = 0; i < ap->NumArgs; ++i)
  2672.   {
  2673.     OutClibType(&cd->Args[i], ap->Args[i].ArgName);
  2674.     if(i < ap->NumArgs-1)
  2675.       DoOutput(", ");
  2676.   }
  2677.   DoOutput(/*(*/")\n{\n%s"/*}*/, (BaseName ? "   BASE_EXT_DECL\n" : ""));
  2678.  
  2679.   if(!noret)
  2680.   {
  2681.     DoOutput("   register ");
  2682.     OutClibType(&cd->ReturnType, "res");
  2683.     DoOutput(" __asm(\"d0\");\n");
  2684.   }
  2685.  
  2686.   if(BaseName)
  2687.     DoOutput("   register struct %s *a6 __asm(\"a6\") = BASE_NAME;\n",
  2688.     GetBaseType());
  2689.  
  2690.   for(i = 0; i < ap->NumArgs; ++i)
  2691.   {
  2692.     j = ap->Args[i].ArgReg;
  2693.     if(a45 && (j == REG_A4 || j == REG_A5))
  2694.       j = REG_D7;
  2695.  
  2696.     DoOutput("   register ");
  2697.     OutClibType(&cd->Args[i], RegNames[j]);
  2698.     DoOutput(" __asm(\"%s\") = %s;\n", RegNames[j], ap->Args[i].ArgName);
  2699.   }
  2700.  
  2701.   if(a45)
  2702.   {
  2703.     DoOutput("   __asm volatile (\"exg d7,%s\\n\\t"/*)*/
  2704.     "jsr a6@(-0x%lx:W)\\n\\texg d7,%s\"\n", RegNames[a45],
  2705.     ap->Bias, RegNames[a45]);
  2706.   }
  2707.   else
  2708.     DoOutput("   __asm volatile (\"jsr a6@(-0x%lx:W)\"\n"/*)*/, ap->Bias);
  2709.  
  2710.   DoOutput(noret ? "   : /* No Output */\n" : "   : \"=r\" (res)\n");
  2711.  
  2712.   DoOutput("   : ");
  2713.   if(BaseName)
  2714.     DoOutput("\"r\" (a6)%s", (ap->NumArgs ? ", ": ""));
  2715.  
  2716.   for(i = 0; i < ap->NumArgs; ++i)
  2717.   {
  2718.     j = ap->Args[i].ArgReg;
  2719.     if(a45 && (j == REG_A4 || j == REG_A5))
  2720.       j = REG_D7;
  2721.  
  2722.     DoOutput("\"r\" (%s)%s", RegNames[j], (i < ap->NumArgs-1 ? ", " : ""));
  2723.   }
  2724.  
  2725.   DoOutput("\n   : \"d0\", \"d1\", \"a0\", \"a1\", \"fp0\", \"fp1\"");
  2726.  
  2727.   if(noret)
  2728.     return DoOutput(/*({*/", \"cc\", \"memory\");\n}\n\n");
  2729.   else
  2730.     return DoOutput(/*({*/", \"cc\", \"memory\");\n   return res;\n}\n\n");
  2731. }
  2732.  
  2733. ULONG CallFunc(ULONG tagmode, STRPTR comment, FuncType Func)
  2734. {
  2735.   struct Comment *com = 0;
  2736.   struct AmiPragma *ap;
  2737.  
  2738.   if(comment)
  2739.     com = (struct Comment *) Comment.First;
  2740.  
  2741.   for(ap = (struct AmiPragma *) AmiPragma.First; ap && !CTRL_C;
  2742.   ap = (struct AmiPragma *) ap->List.Next)
  2743.   {
  2744.     if(BaseName && (ap->Flags & AMIPRAGFLAG_A6USE))
  2745.     {
  2746.       DoError(ERR_A6_NOT_ALLOWED, ap->Line);
  2747.     }
  2748.     else if((ap->Flags & AMIPRAGFLAG_PUBLIC) || (Flags & FLAG_PRIVATE))
  2749.     {
  2750.       while(com && com->Bias <= ap->Bias)
  2751.       {
  2752.     if(!DoOutput(comment, com->Data))
  2753.       return 0;
  2754.     com = (struct Comment *) com->List.Next;
  2755.       }
  2756.  
  2757. #ifdef DEBUG_OLD
  2758.   Printf("Processing %s\n", ap->FuncName);
  2759. #endif
  2760.  
  2761.       if(tagmode != TAGMODE_TAGS && ap->FuncName && !Func(ap, FUNCFLAG_NORMAL, ap->FuncName))
  2762.     return 0;
  2763.       if(ap->AliasName &&
  2764.       (((ap->AliasName->Type & FUNCFLAG_TAG) && tagmode) ||
  2765.       (!(ap->AliasName->Type & FUNCFLAG_TAG) && tagmode != TAGMODE_TAGS)) &&
  2766.       !Func(ap, FUNCFLAG_ALIAS|ap->AliasName->Type, ap->AliasName->AliasName))
  2767.     return 0;
  2768.       if(tagmode && ap->TagName && !Func(ap, FUNCFLAG_TAG, ap->TagName))
  2769.     return 0;
  2770.     }
  2771.   }
  2772.   while(com)
  2773.   {
  2774.     if(!DoOutput(comment, com->Data))
  2775.       return 0;
  2776.     com = (struct Comment *) com->List.Next;
  2777.   }
  2778.   return 1;
  2779. }
  2780.  
  2781. /* ------------------------------------------------------------------ */
  2782.  
  2783. LONG AddClibEntry(STRPTR buffer, STRPTR bufend, ULONG linenum)
  2784. {
  2785.   STRPTR buf = buffer;
  2786.   struct ClibData d, *f;
  2787.  
  2788.   memset(&d, 0, sizeof(struct ClibData));
  2789.   if(!GetCPPType(&d.ReturnType, SkipBlanks(buf)))
  2790.   {
  2791.     DoError(ERR_UNKNOWN_VARIABLE_TYPE, linenum, 0);
  2792.     return 0;
  2793.   }
  2794.   d.FuncName = SkipBlanks(d.ReturnType.TypeStart+d.ReturnType.FullLength);
  2795.   while(*(buf++) != '('/*)*/)
  2796.     ;
  2797.   *(SkipName(d.FuncName)) = 0;
  2798.   buf = SkipBlanksRet(buf);
  2799.  
  2800.   while(*buf != /*(*/')' && buf < bufend)
  2801.   {
  2802.     if(!GetCPPType(&d.Args[d.NumArgs++], buf))
  2803.     {
  2804.       DoError(ERR_UNKNOWN_VARIABLE_TYPE, linenum, d.NumArgs);
  2805.       return 0;
  2806.     }
  2807.  
  2808.     buf += d.Args[d.NumArgs-1].FullLength;
  2809.     while(*buf != ',' && *buf != /*(*/')' && buf < bufend)
  2810.       ++buf;
  2811. #ifdef DEBUG_OLD
  2812.   Printf("Added argument %ld for %s (%ld bytes)\n", d.NumArgs, d.FuncName,
  2813.   d.Args[d.NumArgs-1].FullLength);
  2814. #endif
  2815.     if(*buf == ',')
  2816.       buf = SkipBlanksRet(++buf);
  2817.   }
  2818.  
  2819.   if(d.NumArgs == 1 && IsCPPType(&d.Args[0], CPP_TYPE_VOID))
  2820.     d.NumArgs = 0; /* void arguments are no arguments */
  2821.  
  2822.   if(!(f = (struct ClibData *) AllocListMem(sizeof(struct ClibData))))
  2823.     return -1;
  2824.  
  2825.   CopyMem(&d, f, sizeof(struct ClibData));
  2826.  
  2827.   if(!clibdata)
  2828.     clibdata = f;
  2829.   else
  2830.   {
  2831.     struct ClibData *e = clibdata;
  2832.     while(e->Next)
  2833.       e = e->Next;
  2834.     e->Next = f;
  2835.   }
  2836.  
  2837. #ifdef DEBUG
  2838.   Printf("Added prototype for %s (line %ld, %ld bytes) with %ld args\n",
  2839.   f->FuncName, linenum, buf-buffer, f->NumArgs);
  2840. #endif
  2841.   return buf-buffer;
  2842. }
  2843.  
  2844. LONG ScanClibFile(STRPTR buf, STRPTR bufend)
  2845. {
  2846.   STRPTR linestart = buf;
  2847.   ULONG linenum = 1;
  2848.  
  2849.   while(buf < bufend && !CTRL_C)
  2850.   {
  2851.     if(*buf == '/' && buf[1] == '*')
  2852.     {
  2853.       while(buf < bufend && (*buf != '*' || buf[1] != '/'))
  2854.       {
  2855.         if(*(buf++) == '\n')
  2856.         {
  2857.           ++linenum; linestart = buf;
  2858.         } /* skip comments */
  2859.       }
  2860.     }
  2861.     else if(*buf == '/' && buf[1] == '/')
  2862.     {
  2863.       while(buf < bufend && *buf != '\n')
  2864.         ++buf; /* skip line comments */
  2865.     }
  2866.     else if(*buf == '\n')
  2867.     {
  2868.       linestart = ++buf; ++linenum;
  2869.     }
  2870.     else if(*buf == '('/*)*/)
  2871.     {
  2872.       LONG i;
  2873.  
  2874.       if((i = AddClibEntry(linestart, bufend, linenum)) == -1) /* no memory */
  2875.         return 0;
  2876.       else if(!i)
  2877.       {
  2878.         while(buf < bufend && *buf != '\n')
  2879.           ++buf; /* skip this line */
  2880.       }
  2881.       else
  2882.       {
  2883.         i -= buf-linestart;
  2884.         while(buf < bufend && i-- > 0)
  2885.         {
  2886.           if(*(buf++) == '\n')
  2887.           {
  2888.             linestart = buf;
  2889.             ++linenum;
  2890.           } /* skip this function */
  2891.         }
  2892.       }
  2893.     }
  2894.     else
  2895.       ++buf;
  2896.   } /* while */
  2897.   return 1;
  2898. }
  2899.  
  2900. LONG IsCPPType(struct CPP_NameType *data, UBYTE type)
  2901. {
  2902.   if(!data || data->Flags || data->Type != type || data->PointerDepth)
  2903.     return 0;
  2904.   return type;
  2905. }
  2906.  
  2907. LONG GetCPPType(struct CPP_NameType *data, STRPTR start)
  2908. {
  2909.   ULONG ok = 1;
  2910.   STRPTR u;
  2911.  
  2912.   data->TypeStart = SkipBlanks(start);
  2913.  
  2914.   do
  2915.   {
  2916.     start = SkipBlanks((u = start));
  2917.     if(!strncmp("...",start,3))
  2918.     {
  2919.       data->Type = CPP_TYPE_VARARGS; return 1;
  2920.     }
  2921.     if(CheckKeyword(start, "const", 5))
  2922.     {
  2923.       data->Flags |= CPP_FLAG_CONST; start += 6;
  2924.     }
  2925.     else if(CheckKeyword(start, "signed", 6))
  2926.       start += 7;
  2927.     else if(CheckKeyword(start, "unsigned", 8))
  2928.     {
  2929.       data->Flags |= CPP_FLAG_UNSIGNED; start += 9;
  2930.     }
  2931.     else if(CheckKeyword(start, "struct", 6))
  2932.     {
  2933.       start = SkipBlanks(start+6);
  2934.       data->Flags |= CPP_FLAG_STRUCT;
  2935.       if(*start != '?') /* ? for external types */
  2936.       {
  2937.         start = SkipName((data->StructureName = start));
  2938.         data->StructureLength = start-data->StructureName;
  2939.       }
  2940.       else
  2941.       {
  2942.     data->StructureLength = 0;
  2943.     data->StructureName = "";
  2944.     ++start;
  2945.       }
  2946.     }
  2947.     else if(CheckKeyword(start, "enum", 4))
  2948.     {
  2949.       start = SkipBlanks(start+4);
  2950.       data->Flags |= CPP_FLAG_ENUM;
  2951.       if(*start != '?') /* ? for external types */
  2952.       {
  2953.         start = SkipName((data->StructureName = start));
  2954.         data->StructureLength = start-data->StructureName;
  2955.       }
  2956.       else
  2957.       {
  2958.     data->StructureLength = 0;
  2959.     data->StructureName = "";
  2960.     ++start;
  2961.       }
  2962.     }
  2963.     else if(*start == '*')
  2964.     {
  2965.       ++start; ++data->PointerDepth;
  2966.     }
  2967.     else
  2968.     {
  2969.       ULONG i;
  2970.  
  2971.       for(i = 0; CPP_Field[i].Text; ++i)
  2972.       {
  2973.     if(!strncmp(start, CPP_Field[i].Text, CPP_Field[i].Length))
  2974.     {
  2975.       start += CPP_Field[i].Length;
  2976.       data->Type = CPP_Field[i].Type;
  2977.       data->Flags |= CPP_Field[i].Flags;
  2978.       if(CPP_Field[i].Flags & CPP_FLAG_POINTER)
  2979.         ++data->PointerDepth;
  2980.       break;
  2981.     }
  2982.       }
  2983.       if(CPP_Field[i].Text)
  2984.         continue;
  2985.       else if(extnames)
  2986.       {
  2987.         struct CPP_ExternNames *a = extnames;
  2988.        
  2989.         while(a)
  2990.         {
  2991.           i = strlen(a->Type);
  2992.           if(!strncmp(a->Type, start, i) && !isalnum(start[i]) && 
  2993.           start[i] != '_')
  2994.           {
  2995.             start += i;
  2996.             data->StructureName = a->NameType.StructureName;
  2997.           data->FuncArgs = a->NameType.FuncArgs;
  2998.         data->StructureLength = a->NameType.StructureLength;
  2999.         data->PointerDepth += a->NameType.PointerDepth;
  3000.         data->Type = a->NameType.Type;
  3001.         data->Flags |= a->NameType.Flags;
  3002.         break;
  3003.           }
  3004.      
  3005.       /* check types here */
  3006.           a = a->Next;
  3007.         }
  3008.         if(a)
  3009.           continue;
  3010.       }
  3011.       break;
  3012.     }
  3013.   } while(1);
  3014.  
  3015.   if(start != SkipBlanks(u)) /* we broke the loop after increasing start */
  3016.     u = start;
  3017.  
  3018.   data->TypeLength = u - (data->TypeStart);
  3019.   data->FullLength = data->TypeLength;
  3020.  
  3021.   if(*u == '('/*)*/)
  3022.   {
  3023.     ok = 0;
  3024.     u = SkipBlanks(++u);
  3025.     if(*u == '*')
  3026.     {
  3027.       u = SkipBlanks(SkipName(SkipBlanks(++u)));
  3028.       if(*u == /*(*/')')
  3029.       {
  3030.         u = SkipBlanks(++u);
  3031.         if(*u == '('/*)*/)
  3032.         {
  3033.           data->Flags |= CPP_FLAG_FUNCTION;
  3034.           data->FuncArgs = u;
  3035.           ok = 1;
  3036.           u = SkipBlanks(++u);
  3037.           if(*u == /*(*/')')
  3038.             data->FuncArgs = 0;
  3039.       else
  3040.       {
  3041.         ULONG d = 0;
  3042.         while(d || *u != /*(*/')')
  3043.         {
  3044.           if(*u == '('/*)*/)
  3045.             ++d;
  3046.           else if(*u == /*(*/')')
  3047.             --d;
  3048.           ++u;
  3049.         }
  3050.         data->ArgsLength = u+1 - (data->FuncArgs);
  3051.       }
  3052.           data->FullLength = u+1 - (data->TypeStart);
  3053.         }
  3054.       }
  3055.     }
  3056.   }
  3057.  
  3058.   if(data->PointerDepth)
  3059.     data->Flags |= CPP_FLAG_POINTER;
  3060.  
  3061.   if((!data->Type && !data->Flags) || !ok)
  3062.     return 0;
  3063.   return 1;
  3064. }
  3065.  
  3066. struct ClibData *GetClibFunc(STRPTR name, struct AmiPragma *ap, ULONG flags)
  3067. {
  3068.   struct ClibData *d = clibdata;
  3069.  
  3070.   while(d && strcmp(name, d->FuncName))
  3071.     d = d->Next;
  3072.  
  3073.   if(!d)
  3074.   {
  3075.     if(!(ap->Flags & AMIPRAGFLAG_NOCLIB))
  3076.     {
  3077.       DoError(ERR_PROTOTYPE_MISSING, 0, name);
  3078.       ap->Flags |= AMIPRAGFLAG_NOCLIB;
  3079.     }
  3080.   }
  3081.   else if(ap->CallArgs != d->NumArgs && (!(flags & FUNCFLAG_TAG) ||
  3082.   ap->CallArgs+1 != d->NumArgs))
  3083.   {
  3084.     if(!(ap->Flags & (AMIPRAGFLAG_CLIBARGCNT|AMIPRAGFLAG_DIDWARN)))
  3085.     {
  3086.       DoError(ERR_CLIB_ARG_COUNT, 0, name, d->NumArgs, ap->NumArgs);
  3087.       ap->Flags |= AMIPRAGFLAG_CLIBARGCNT;
  3088.     }
  3089.     return 0;
  3090.   }
  3091.  
  3092.   return d;  
  3093. }
  3094.  
  3095. LONG CheckKeyword(STRPTR string, STRPTR keyword, LONG size)
  3096. {
  3097.   if(!strncmp(string, keyword, size))
  3098.   {
  3099.     string += size;
  3100.     if(*string == ' ' || *string == '\t' || *string == '\n')
  3101.       return size;
  3102.   }
  3103.   return 0;
  3104. }
  3105.  
  3106. /* return non zero, when ok, return 0xFFFFFFFF when STRPTR and not flags */
  3107. ULONG CopyCPPType(STRPTR buffer, ULONG flag, struct ClibData *cd,
  3108. struct AmiArgs *args)
  3109. {
  3110. /* when flag, then STRPTR is unsigned char * mode, else signed char * */
  3111.   ULONG ret = 1;
  3112.   ULONG i, j, k = 0;
  3113.  
  3114.   for(i = 0; i < cd->NumArgs; ++i)
  3115.   {
  3116.     struct CPP_NameType *nt;
  3117.  
  3118.     nt = &cd->Args[i];
  3119.  
  3120.     if(!flag && (nt->Flags & CPP_FLAG_STRPTR))
  3121.       ret = 0xFFFFFFFF;
  3122.  
  3123.     if(args && (Flags & FLAG_LOCALREG) && (nt->Type != CPP_TYPE_VARARGS))
  3124.     {
  3125.       *(buffer++) = CPP_TYPE_REGISTER;
  3126.       *(buffer++) = args[k].ArgReg + (args[k].ArgReg < 10 ? '0' : 'A'-10);
  3127.     }
  3128.     if(nt->Flags & CPP_FLAG_FUNCTION)
  3129.     {
  3130.       *(buffer++) = CPP_TYPE_POINTER; *(buffer++) = CPP_TYPE_FUNCTION;
  3131.     }
  3132.     for(j = 0; j < nt->PointerDepth; ++j)
  3133.       *(buffer++) = CPP_TYPE_POINTER;
  3134.     if(nt->Flags & CPP_FLAG_CONST)
  3135.       *(buffer++) = CPP_TYPE_CONST;
  3136.     if((nt->Flags & CPP_FLAG_UNSIGNED) || (flag && (nt->Flags & CPP_FLAG_STRPTR)))
  3137.       *(buffer++) = CPP_TYPE_UNSIGNED;
  3138.     if(nt->Flags & CPP_FLAG_ENUM)
  3139.       *(buffer++) = CPP_TYPE_ENUM;
  3140.     if(nt->Type)
  3141.       *(buffer++) = cd->Args[i].Type;
  3142.     else
  3143.     {
  3144.       ULONG i;
  3145.       sprintf(buffer, "%02ld", (ULONG) nt->StructureLength); buffer += 2;
  3146.       for(i = 0; i < nt->StructureLength; ++i)
  3147.     *(buffer++) = nt->StructureName[i];
  3148.     }
  3149.     if(nt->Flags & CPP_FLAG_FUNCTION)
  3150.     {
  3151. //      if(nt.FuncArgs)
  3152. //      {
  3153. //        ******** do something here
  3154. //        while(*buffer)
  3155. //          ++buffer;
  3156. //      }
  3157.       *(buffer++) = CPP_TYPE_FUNCEND;
  3158.     }
  3159.     ++k;
  3160.     if(IsCPPType(nt, CPP_TYPE_DOUBLE))    /* double needs 2 registers */
  3161.       ++k;
  3162.   }
  3163.  
  3164.   *(buffer) = 0;
  3165.  
  3166.   return ret;
  3167. }
  3168.  
  3169. ULONG OutClibType(struct CPP_NameType *nt, STRPTR txt)
  3170. {
  3171.   DoOutputDirect(nt->TypeStart, nt->TypeLength);
  3172.   if(!DoOutput((nt->Flags & CPP_FLAG_FUNCTION) ? (txt ? " (*%s)" : " (*)") :
  3173.   (txt ? " %s" : ""), txt))
  3174.     return 0;
  3175.  
  3176.   if(nt->Flags & CPP_FLAG_FUNCTION)
  3177.   {
  3178.     if(nt->FuncArgs)
  3179.       DoOutputDirect(nt->FuncArgs, nt->ArgsLength);
  3180.     else
  3181.       return DoOutput("()");
  3182.   }
  3183.  
  3184.   return 1;
  3185. }
  3186.  
  3187. /* ------------------------------------------------------------------ */
  3188.  
  3189. ULONG CallPrag(ULONG tagmode, STRPTR type, FuncType Func)
  3190. {
  3191.   if(type)
  3192.     if((*type && !DoOutput("#if%s\n", type)) ||
  3193.     !(CallFunc(tagmode, tagmode ? 0 : "/%s */\n", Func)) ||
  3194.     (*type && !DoOutput("#endif\n")) || CTRL_C)
  3195.       return 0;
  3196.   return 1;
  3197. }
  3198.  
  3199. ULONG CreatePragmaFile(STRPTR amicall, STRPTR libcall, STRPTR amitags,
  3200. STRPTR libtags, ULONG mode)
  3201. {
  3202.   switch(mode)
  3203.   {
  3204.   case PRAGMODE_PRAGLIB: DoOutput("#ifndef _INCLUDE_PRAGMA_%s_LIB_H\n#define _INCLUDE_PRAGMA_%s_LIB_H\n",
  3205.     ShortBaseNameUpper, ShortBaseNameUpper); break;
  3206.   case PRAGMODE_PRAGSLIB: DoOutput("#ifndef PRAGMAS_%s_LIB_H\n#define PRAGMAS_%s_LIB_H\n",
  3207.     ShortBaseNameUpper, ShortBaseNameUpper); break;
  3208.   case PRAGMODE_PRAGSPRAGS: DoOutput("#ifndef PRAGMAS_%s_PRAGMAS_H\n#define PRAGMAS_%s_PRAGMAS_H\n",
  3209.     ShortBaseNameUpper, ShortBaseNameUpper); break;
  3210.   case PRAGMODE_NONE: break;
  3211.   default: return 0;
  3212.   }
  3213.  
  3214.   if(HEADER)
  3215.   {
  3216.     DoOutput("\n");
  3217.     DoOutputDirect(HEADER, headersize);
  3218.   }
  3219.  
  3220.   if(mode != PRAGMODE_NONE && !DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
  3221.   "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
  3222.     return 0;
  3223.  
  3224.   if((Flags & FLAG_EXTERNC) &&
  3225.   !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
  3226.     return 0;
  3227.  
  3228.   if(Flags & FLAG_GNUPRAG)
  3229.   {
  3230.     DoOutput("#ifdef " TEXT_GNUC "\n#include <inline/%s.h>\n#endif\n",
  3231.     ShortBaseName);
  3232.     Flags |= FLAG_DONE;
  3233.   }
  3234.  
  3235.   if(
  3236.   !CallPrag(TAGMODE_NORMAL, amicall, FuncAMICALL) ||
  3237.   !CallPrag(TAGMODE_NORMAL, libcall, FuncLIBCALL))
  3238.     return 0;
  3239.  
  3240.   if(tagfuncs)
  3241.   {
  3242.     if(
  3243.     !CallPrag(TAGMODE_TAGS, amitags, FuncAMICALL) ||
  3244.     !CallPrag(TAGMODE_TAGS, libtags, FuncLIBCALL))
  3245.       return 0;
  3246.   }
  3247.  
  3248.   if((Flags & FLAG_EXTERNC) &&
  3249.   !DoOutput("\n#ifdef __cplusplus\n}\n#endif\n"))
  3250.     return 0;
  3251.  
  3252.   switch(mode)
  3253.   {
  3254.   case PRAGMODE_PRAGLIB: DoOutput("\n#endif\t/*  _INCLUDE_PRAGMA_%s_LIB_H  */\n",
  3255.     ShortBaseNameUpper); break;
  3256.   case PRAGMODE_PRAGSLIB: DoOutput("\n#endif\t/*  PRAGMAS_%s_LIB_H  */\n",
  3257.     ShortBaseNameUpper); break;
  3258.   case PRAGMODE_PRAGSPRAGS: DoOutput("\n#endif\t/*  PRAGMAS_%s_PRAGMA_H  */\n",
  3259.     ShortBaseNameUpper); break;
  3260.   case PRAGMODE_NONE: break;
  3261.   default: return 0;
  3262.   }
  3263.   return Output_Error;
  3264. }
  3265.  
  3266. ULONG CreateCSTUBSFile(void)
  3267. {
  3268.   DoOutput("#ifndef _INCLUDE_%s_CSTUBS_H\n#define _INCLUDE_%s_CSTUBS_H\n",
  3269.     ShortBaseNameUpper, ShortBaseNameUpper);
  3270.  
  3271.   if(!clibdata)
  3272.   {
  3273.     DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
  3274.   }
  3275.  
  3276.   if(HEADER)
  3277.   {
  3278.     DoOutput("\n");
  3279.     DoOutputDirect(HEADER, headersize);
  3280.   }
  3281.  
  3282.   if(!DoOutput("\n#ifndef CLIB_%s_PROTOS_H\n#include "
  3283.   "<clib/%s_protos.h>\n#endif\n\n", ShortBaseNameUpper, ShortBaseName))
  3284.     return 0;
  3285.  
  3286.   if(!CallFunc(TAGMODE_TAGS, "/%s */\n", FuncCSTUBS))
  3287.     return 0;
  3288.  
  3289.   return DoOutput("#endif\t/*  _INCLUDE_%s_CSTUBS_H  */\n",
  3290.   ShortBaseNameUpper);
  3291. }
  3292.  
  3293. ULONG CreateLVOFile(ULONG mode)
  3294. {
  3295.   STRPTR data = "_LVO_I";
  3296.  
  3297.   if(mode == 2 || mode == 4)
  3298.     data = "_LIB_I";
  3299.  
  3300.   if(!DoOutput("\t\tIFND LIBRARIES_%s%s\nLIBRARIES_%s%s\tSET\t1\n\n",
  3301.   ShortBaseNameUpper, data, ShortBaseNameUpper, data) ||
  3302.   (HEADER && (!DoOutput("\n") || !DoOutputDirect(HEADER, headersize))) ||
  3303.   (mode <= 2 && !CallFunc(TAGMODE_NORMAL, 0, FuncLVOXDEF)) ||
  3304.   !CallFunc(TAGMODE_NORMAL, "\n%s", FuncLVO) ||
  3305.   !DoOutput("\n\n\t\tENDC\n") || CTRL_C)
  3306.     return 0;
  3307.  
  3308.   return 1;
  3309. }
  3310.  
  3311. ULONG CreateAsmStubs(ULONG mode, ULONG callmode)
  3312. {
  3313.   /* 1 = Text, 2 = Code */
  3314.   switch(mode)
  3315.   {
  3316.   case 1:
  3317.     if((HEADER && (!DoOutput("\n") || !DoOutputDirect(HEADER, headersize))) ||
  3318.     !DoOutput("\tSECTION\t \"%s_STUBS\",CODE\n\tXREF\t_%s\n",
  3319.     ShortBaseNameUpper, BaseName) ||
  3320.     !CallFunc(callmode, 0, FuncAsmText))
  3321.       return 0;
  3322.     break;
  3323.   case 2:
  3324.     if(!CallFunc(callmode, 0, FuncAsmCode))
  3325.       return 0;
  3326.     break;
  3327.   }
  3328.  
  3329.   if(CTRL_C)
  3330.     return 0;
  3331.   return 1;
  3332. }
  3333.  
  3334. ULONG CreateProtoFile(ULONG Type)
  3335. {
  3336.   STRPTR str1 = "pragma", str2 = "lib";
  3337.  
  3338.   DoOutput("#ifndef _PROTO_%s_H\n#define _PROTO_%s_H\n", ShortBaseNameUpper,
  3339.   ShortBaseNameUpper);
  3340.  
  3341.   if(HEADER)
  3342.   {
  3343.     DoOutput("\n");
  3344.     DoOutputDirect(HEADER, headersize);
  3345.   }
  3346.  
  3347.   switch(Type)
  3348.   {
  3349.     case 4: str1 = "pragmas"; /* no break; */
  3350.     case 2: str2 = "pragmas"; break;
  3351.     case 3: str1 = "pragmas"; break;
  3352.     case 5: str1 = "local"; str2 = "loc"; break;
  3353.   }
  3354.  
  3355.   DoOutput("\n#ifndef EXEC_TYPES_H\n#include <exec/types.h>\n#endif\n");
  3356.   if(Type != 5)
  3357.     DoOutput("#ifndef CLIB_%s_PROTOS_H\n#include <clib/%s_protos.h>\n#endif\n",
  3358.     ShortBaseNameUpper, ShortBaseName);
  3359.   if(Type >= 6)
  3360.   {
  3361.     DoOutput("\n#ifdef " TEXT_GNUC "\n#include <inline/%s.h>\n",
  3362.     ShortBaseName);
  3363.     if(Type != 7)
  3364.       DoOutput("#else");
  3365.   }
  3366.   if(Type != 7)
  3367.     DoOutput("\n#include <%s/%s_%s.h>\n", str1, ShortBaseName, str2);
  3368.   if(Type >= 6)
  3369.     DoOutput("#endif\n");
  3370.  
  3371.   if(BaseName)
  3372.   {
  3373.     DoOutput("\n#ifndef __NOLIBBASE__\n");
  3374.     DoOutput("extern struct %s *", GetBaseType());
  3375.     if(Type >= 7)
  3376.       DoOutput("\n#ifdef __CONSTLIBBASEDECL__\n__CONSTLIBBASEDECL__\n"
  3377.       "#endif\n");
  3378.     DoOutput("%s;\n", BaseName);
  3379.     DoOutput("#endif\n");
  3380.   }
  3381.  
  3382.   Flags |= FLAG_DONE;
  3383.  
  3384.   return DoOutput("\n#endif\t/*  _PROTO_%s_H  */\n", ShortBaseNameUpper);
  3385. }
  3386.  
  3387. ULONG CreateLocalData(STRPTR to, ULONG callmode, STRPTR clibbuf,
  3388. ULONG clibsize)
  3389. {
  3390.   UBYTE a[40];
  3391.  
  3392.   DoOutput("#ifndef _INCLUDE_PROTO_%s_LOC_H\n#define _INCLUDE_PROTO_%s_LOC_H\n\n",
  3393.   ShortBaseNameUpper, ShortBaseNameUpper);
  3394.  
  3395.   if(HEADER)
  3396.   {
  3397.     DoOutput("\n");
  3398.     DoOutputDirect(HEADER, headersize);
  3399.   }
  3400.  
  3401.   { /* copies the include lines */
  3402.     STRPTR str = clibbuf, strend = clibbuf + clibsize;
  3403.     ULONG i = 0;
  3404.  
  3405.     /* works too, when no clibbuf, because then following is everytime false */
  3406.     while(str < strend)
  3407.     {
  3408.       if(!strncmp(str, "#include", 8))
  3409.       {
  3410.     DoOutput("%s\n",str); ++i;
  3411.       }
  3412.       while(*(str++))
  3413.     ;
  3414.     }
  3415.     DoOutput(i ? "\n" : "#include <exec/types.h>\n\n");
  3416.   }
  3417.  
  3418.   if((Flags & FLAG_EXTERNC) &&
  3419.   !DoOutput("#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n"))
  3420.     return 0;
  3421.  
  3422.   if(!CallFunc(callmode, 0, FuncLocText))
  3423.     return 0;
  3424.  
  3425.   if((Flags & FLAG_EXTERNC) &&
  3426.   !DoOutput("#ifdef __cplusplus\n}\n#endif\n\n"))
  3427.     return 0;
  3428.  
  3429.   DoOutput("#endif\t/*  _INCLUDE_PROTO_%s_LOC_H  */\n", ShortBaseNameUpper);
  3430.   Out(out.size); /* clears buffer */
  3431.  
  3432.   sprintf(a, "%s_loc.lib", ShortBaseName);
  3433.   if(!CloseDest(to) || !(out.file = Open(a, MODE_NEWFILE)))
  3434.     return 0;
  3435.  
  3436.   CallFunc(callmode, 0, FuncLocCode);
  3437.   
  3438.   return CloseDest(a);
  3439. }
  3440.  
  3441. ULONG CreateInline(ULONG mode)
  3442. {
  3443.   if(!clibdata)
  3444.   {
  3445.     DoError(ERR_NOPROTOTYPES_FILE, 0); return 1;
  3446.   }
  3447.  
  3448.   DoOutput("#ifndef _INLINE_%s_H\n#define _INLINE_%s_H\n\n",
  3449.   ShortBaseNameUpper, ShortBaseNameUpper);
  3450.  
  3451.   if(HEADER)
  3452.   {
  3453.     DoOutput("\n");
  3454.     DoOutputDirect(HEADER, headersize);
  3455.   }
  3456.  
  3457.   if(mode)
  3458.   {
  3459.     DoOutput("#ifndef __INLINE_STUB_H\n#include <inline/stubs.h>\n#endif\n\n");
  3460.     if(mode == 2)
  3461.       Flags |= FLAG_INLINESTUB;
  3462.   }
  3463.   else
  3464.   {
  3465.     DoOutput("#ifndef __INLINE_MACROS_H\n#include <inline/macros.h>\n#endif\n\n");
  3466.     Flags |= FLAG_INLINENEW;
  3467.   }
  3468.  
  3469.   if(BaseName)
  3470.   {
  3471.     if(mode)
  3472.       DoOutput("#ifndef BASE_EXT_DECL\n#define BASE_EXT_DECL\n"
  3473.       "#define BASE_EXT_DECL0 extern struct %s *%s;\n#endif\n"
  3474.       "#ifndef BASE_PAR_DECL\n#define BASE_PAR_DECL\n"
  3475.       "#define BASE_PAR_DECL0 void\n#endif\n"
  3476.       "#ifndef BASE_NAME\n#define BASE_NAME %s\n#endif\n\n"
  3477.       "BASE_EXT_DECL0\n\n", GetBaseType(), BaseName, BaseName);
  3478.     else
  3479.       DoOutput("#ifndef %s_BASE_NAME\n#define %s_BASE_NAME %s\n#endif\n\n",
  3480.       ShortBaseNameUpper, ShortBaseNameUpper, BaseName);
  3481.   }
  3482.  
  3483.   if(!CallFunc(TAGMODE_BOTH, "/%s */\n", FuncInline))
  3484.     return 0;
  3485.  
  3486.   if(mode && BaseName)
  3487.     DoOutput("#undef BASE_EXT_DECL\n#undef BASE_EXT_DECL0\n"
  3488.     "#undef BASE_PAR_DECL\n#undef BASE_PAR_DECL0\n#undef BASE_NAME\n\n");
  3489.  
  3490.   return DoOutput("#endif /*  _INLINE_%s_H  */\n", ShortBaseNameUpper);
  3491. }
  3492.  
  3493. /* ------------------------------------------------------------------ */
  3494.  
  3495. ULONG GetName(struct NameList *t, struct ShortListRoot *p, ULONG args)
  3496. {
  3497.   struct NameList *p2 = (struct NameList *) p->First;
  3498.   struct AmiPragma ap;
  3499.   ap.FuncName = t->NormName;
  3500.   ap.NumArgs = 1;
  3501.   ap.Args[0].ArgName = (args ? "args" : "tags");
  3502.   if(!MakeTagFunction(&ap))
  3503.     return 0;
  3504.  
  3505.   while(p2 && strcmp(p2->PragName, ap.TagName))
  3506.    p2 = (struct NameList *) p2->List.Next;
  3507.  
  3508.   if(!p2)
  3509.     return 0;
  3510.  
  3511.   t->Type = (args ? NTP_ARGS : NTP_TAGS);
  3512.   t->PragName = ap.TagName;
  3513.   RemoveItem(p, (struct ShortList *) p2);
  3514.  
  3515. #ifdef DEBUG_OLD
  3516.   VPrintf("GetName: name matches - %s _ %s\n", &t->NormName);
  3517. #endif
  3518.  
  3519.   return 1;
  3520. }
  3521.  
  3522. void OptimizeFDData(struct PragData *pd)
  3523. {
  3524. #ifdef DEBUG_OLD
  3525.   PutStr("OptimizeFDData\n");
  3526. #endif
  3527.  
  3528.   while(pd && !CTRL_C)
  3529.   {
  3530.     if(pd->NumNames > 1)
  3531.     {
  3532.       struct ShortListRoot n = {0,0,0}, p = {0,0,0};
  3533.       struct NameList *t;
  3534.       while(pd->Name.First)    /* sorts in AmiCall and TagCall */
  3535.       {
  3536.     t = (struct NameList *) pd->Name.First;
  3537.  
  3538.     RemoveItem(&pd->Name, (struct ShortList *) t);
  3539.     AddItem(t->PragName ? &p : &n, (struct ShortList *) t);
  3540.       }
  3541.  
  3542.       if(p.First)
  3543.       {
  3544.     t = (struct NameList *) n.First;
  3545.     while(p.First && t)
  3546.     {
  3547.       if(!GetName(t, &p, 0))
  3548.       {
  3549.         GetName(t, &p, 1);
  3550.       }
  3551.       if(t->PragName)
  3552.       {
  3553.         struct NameList *t2 = (struct NameList *) t->List.Next;
  3554.         RemoveItem(&n, (struct ShortList *)t);
  3555.         AddItem(&pd->Name, (struct ShortList *) t);
  3556.         t = t2;
  3557.       }
  3558.       else
  3559.         t = (struct NameList *) t->List.Next;
  3560.     }
  3561.     while(p.First)
  3562.     {
  3563.       if(n.First)
  3564.       {
  3565.         t = (struct NameList *) n.First;
  3566.         t->PragName = ((struct NameList *)(p.First))->PragName;
  3567.         RemoveItem(&n, (struct ShortList *) t);
  3568. #ifdef DEBUG_OLD
  3569.         VPrintf("OptimizeFDData: names together - %s _ %s\n", &t->NormName);
  3570. #endif
  3571.         t->Type = NTP_UNKNOWN;
  3572.       }
  3573.       else
  3574.       {
  3575.         ULONG i;
  3576.  
  3577.         t = (struct NameList *) p.First;
  3578.         i = strlen(t->PragName);
  3579.         t->NormName = DupString(t->PragName, i+1);
  3580.         t->NormName[i++] = 'A';
  3581.         t->NormName[i] = 0;
  3582.         t->Type = NTP_TAGS;
  3583. #ifdef DEBUG_OLD
  3584.         VPrintf("OptimizeFDData: NormName created - %s _ %s\n", &t->NormName);
  3585. #endif
  3586.       }
  3587.  
  3588.       AddItem(&pd->Name, (struct ShortList *) t);
  3589.       RemoveItem(&p, p.First);
  3590.     }
  3591.       }
  3592.  
  3593.       AddItem(&pd->Name, n.First); /* add left NormNames */
  3594.     }
  3595.     pd = (struct PragData *) pd->List.Next;
  3596.   }
  3597. }
  3598.  
  3599. ULONG MakeFD(struct PragList *pl)
  3600. {
  3601.   struct PragData *pd = (struct PragData *) pl->Data.First;
  3602.   ULONG bias;
  3603.  
  3604. #ifdef DEBUG_OLD
  3605.   PutStr("MakeFD\n");
  3606. #endif
  3607.   bias = pd->Bias;
  3608.  
  3609.   OptimizeFDData(pd);
  3610. #ifdef DEBUG_OLD
  3611.   PutStr("MakeFD: after Optimizing\n");
  3612. #endif
  3613.   DoOutput("##base _%s\n##bias %ld\n##public\n", pl->Basename, bias);
  3614.  
  3615.   while(pd && !CTRL_C && Output_Error)
  3616.   {
  3617.     struct NameList *n = (struct NameList *) pd->Name.First;
  3618.  
  3619.     if(bias != pd->Bias)
  3620.       DoOutput("##bias %ld\n", (bias = pd->Bias));
  3621.  
  3622.     while(n)
  3623.     {
  3624.       STRPTR lastpar = "last";
  3625.       ULONG i;
  3626.  
  3627.       if(n->Type == NTP_TAGS)
  3628.     lastpar = "tags";
  3629.       else if(n->Type == NTP_ARGS)
  3630.     lastpar = "args";
  3631.  
  3632.       DoOutput("%s("/*)*/,n->NormName);
  3633.       if(!pd->NumArgs)
  3634.     DoOutput(/*(*/")()\n");
  3635.       else
  3636.       {
  3637.     for(i = 0; i < pd->NumArgs-1; ++i)
  3638.       DoOutput("par%ld,",i+1);
  3639.     DoOutput("%s)(", lastpar);
  3640.     for(i = 0; i < pd->NumArgs-1; ++i)
  3641.       DoOutput("%s,", RegNames[pd->ArgReg[i]]);
  3642.     DoOutput("%s)\n", RegNames[pd->ArgReg[i]]);
  3643.  
  3644.     if(n->Type == NTP_UNKNOWN)
  3645.     {
  3646.       ULONG i;
  3647.       for(i = 0; n->NormName[i] == n->PragName[i]; ++i)
  3648.         ;
  3649.       DoOutput("*tagcall");
  3650.       if(n->NormName[i])
  3651.         DoOutput("-%s", n->NormName+i);
  3652.       if(n->PragName[i])
  3653.         DoOutput("+%s", n->PragName+i);
  3654.  
  3655.       DoOutput("\n");
  3656.     }
  3657.       }
  3658.       if((n = (struct NameList *) n->List.Next))
  3659.     DoOutput("##bias %ld\n", pd->Bias);
  3660.       Flags |= FLAG_DONE;
  3661.     }
  3662.  
  3663.     pd = (struct PragData *)pd->List.Next; bias += 6;
  3664.   }
  3665.  
  3666.   if(CTRL_C)
  3667.     return 0;
  3668.  
  3669.   DoOutput("##end\n");
  3670.  
  3671.   return Output_Error;
  3672. }
  3673.  
  3674. ULONG AddFDData(struct ShortListRoot *pls, struct FDData *fd)
  3675. {
  3676.   struct NameList *t;
  3677.   struct PragList *pl = (struct PragList *) pls->First;
  3678.   struct PragData *pd;
  3679.  
  3680.   while(pl && strcmp(pl->Basename, fd->Basename))
  3681.     pl = (struct PragList *) pl->List.Next;
  3682.  
  3683.   if(!pl)
  3684.   {
  3685. #ifdef DEBUG_OLD
  3686.   VPrintf("AddFDData: New PragList - %s\n", &fd->Basename);
  3687. #endif
  3688.     if(!(pl = (struct PragList *) NewItem(pls)))
  3689.       return 100;
  3690.     pl->Basename = fd->Basename;
  3691.     pl->Data.Size = sizeof(struct PragData);
  3692.     AddItem(pls, (struct ShortList *) pl);
  3693.   }
  3694.  
  3695.   if((pd = (struct PragData *) pl->Data.First))
  3696.   {
  3697.     while(pd->List.Next && ((struct PragData *) pd->List.Next)->Bias
  3698.     <= fd->Bias)
  3699.       pd = (struct PragData *) pd->List.Next;
  3700.   }
  3701.  
  3702.   if(!pd || pd->Bias != fd->Bias)
  3703.   {
  3704.     struct PragData *pd2;
  3705. #ifdef DEBUG_OLD
  3706.     {
  3707.       ULONG args[2];
  3708.       args[0] = fd->Bias;
  3709.       args[1] = fd->NumArgs;
  3710.       VPrintf("AddFDData: New PragData - %ld, %ld\n", &args);
  3711.     }
  3712. #endif
  3713.     if(!(pd2 = (struct PragData *) NewItem(&pl->Data)))
  3714.       return 100;
  3715.     pd2->Bias = fd->Bias;
  3716.     CopyMem(fd->ArgReg, pd2->ArgReg, MAXREG);
  3717.     pd2->NumArgs = fd->NumArgs;
  3718.     pd2->Name.Size = sizeof(struct NameList);
  3719.     if(!pd)
  3720.       AddItem(&pl->Data, (struct ShortList *) pd2);
  3721.     else if(pd->Bias > fd->Bias) /* Insert at start */
  3722.     {
  3723.       pd2->List.Next = pl->Data.First;
  3724.       pl->Data.First = (struct ShortList *) pd2;
  3725.     }
  3726.     else /* Insert the entry */
  3727.     {
  3728.       pd2->List.Next = pd->List.Next;
  3729.       pd->List.Next = (struct ShortList *) pd2;
  3730.     }
  3731.     pd = pd2;
  3732.   }
  3733.   else
  3734.   {
  3735.     ULONG i = fd->NumArgs;
  3736.     if(fd->NumArgs != pd->NumArgs)
  3737.     {
  3738. #ifdef DEBUG_OLD
  3739.       Printf("ArgNum %ld != %ld\n", fd->NumArgs, pd->NumArgs);
  3740. #endif
  3741.       return ERR_DIFFERENT_TO_PREVIOUS;
  3742.     }
  3743.  
  3744.     while(i--)
  3745.     {
  3746.       if(fd->ArgReg[i] != pd->ArgReg[i])
  3747.       {
  3748. #ifdef DEBUG_OLD
  3749.         Printf("ArgReg %lx != %lx\n", fd->ArgReg[i], pd->ArgReg[i]);
  3750. #endif
  3751.     return ERR_DIFFERENT_TO_PREVIOUS;
  3752.       }
  3753.     }
  3754.   }
  3755.  
  3756.   t = (struct NameList *) pd->Name.First;    /* skips same names */
  3757.   while(t && strcmp(fd->Name, fd->Mode ? t->PragName : t->NormName))
  3758.     t = (struct NameList *) t->List.Next;
  3759.  
  3760.   if(t)
  3761.     return 0;
  3762.  
  3763.   if(!(t = (struct NameList *) NewItem(&pd->Name)))
  3764.     return 100;
  3765.   if(fd->Mode)
  3766.     t->PragName = fd->Name;
  3767.   else
  3768.     t->NormName = fd->Name;
  3769.   AddItem(&pd->Name, (struct ShortList *) t);
  3770.   ++(pd->NumNames);
  3771. #ifdef DEBUG_OLD
  3772.   VPrintf("AddFDData: New NameList - %s\n", &fd->Name);
  3773. #endif
  3774.   return 0;
  3775. }
  3776.  
  3777. UBYTE GetHexValue(UBYTE data)
  3778. {
  3779.   if(data >= 'a')
  3780.     return (UBYTE) (data - 'a' + 10);
  3781.   else if(data >= 'A')
  3782.     return (UBYTE) (data - 'A' + 10);
  3783.   else
  3784.     return (UBYTE) (data - '0');
  3785. }
  3786.  
  3787. UBYTE GetDoubleHexValue(UBYTE *data)
  3788. {
  3789.   return (UBYTE)((GetHexValue(*data)<<4)+GetHexValue(data[1]));
  3790. }
  3791.  
  3792. ULONG GetLibData(struct FDData *fd)
  3793. {
  3794.   ULONG i;
  3795.   fd->Name = SkipBlanks(in.pos);
  3796.   in.pos = SkipName(fd->Name); *(in.pos++) = 0;
  3797.   in.pos = SkipBlanks(in.pos);
  3798.   fd->Bias = strtoul(in.pos, 0, 16);
  3799.   in.pos = SkipName(SkipBlanks(SkipName(in.pos)));
  3800.   if((fd->NumArgs = GetHexValue(*(--in.pos))) > MAXREGNF - 2)
  3801.     return ERR_TO_MUCH_ARGUMENTS;
  3802.   --in.pos; /* skips return register */
  3803.   for(i = 0; i < fd->NumArgs; ++i)
  3804.   {
  3805.     if((fd->ArgReg[i] = GetHexValue(*(--in.pos))) > REG_A5)
  3806.       return ERR_EXPECTED_REGISTER_NAME;
  3807.   }
  3808.   return 0;
  3809. }
  3810.  
  3811. ULONG GetFlibData(struct FDData *fd)
  3812. {
  3813.   ULONG i;
  3814.   fd->Name = SkipBlanks(in.pos);
  3815.   in.pos = SkipName(fd->Name); *(in.pos++) = 0;
  3816.   in.pos = SkipBlanks(in.pos);
  3817.   fd->Bias = strtoul(in.pos, 0, 16);
  3818.   in.pos = SkipName(SkipBlanks(SkipName(in.pos))) - 2;
  3819.   if((fd->NumArgs = GetDoubleHexValue(in.pos)) > MAXREG-2)
  3820.     return ERR_TO_MUCH_ARGUMENTS;
  3821.   in.pos -= 2; /* skips return register */
  3822.   for(i = 0; i < fd->NumArgs; ++i)
  3823.   {
  3824.     in.pos -= 2;
  3825.     if((fd->ArgReg[i] = GetDoubleHexValue(in.pos)) >= MAXREG)
  3826.       return ERR_EXPECTED_REGISTER_NAME;
  3827.     else if(fd->ArgReg[i] >= REG_FP0 && (Flags & FLAG_NOFPU))
  3828.       return ERR_FLOATARG_NOT_ALLOWED;
  3829.   }
  3830.   return 0;
  3831. }
  3832.  
  3833. ULONG GetAmiData(struct FDData *fd)
  3834. {
  3835.   STRPTR endptr;
  3836.   in.pos = SkipBlanks(in.pos);
  3837.   if(*in.pos != '('/*)*/)
  3838.     return ERR_EXPECTED_OPEN_BRACKET;
  3839.   fd->Basename = ++in.pos;
  3840.   in.pos = SkipBlanks(endptr = SkipName(in.pos));
  3841.   if(*in.pos != ',')
  3842.     return ERR_EXPECTED_COMMA;
  3843.   *endptr = 0;
  3844.   in.pos = SkipBlanks(++in.pos);
  3845.   if(!strncmp(in.pos, "0x", 2))
  3846.     fd->Bias = strtoul(in.pos+2, 0, 16);
  3847.   else
  3848.     fd->Bias = strtoul(in.pos, 0, 10);
  3849.  
  3850.   in.pos = SkipBlanks(SkipName(in.pos));
  3851.   if(*in.pos != ',')
  3852.     return ERR_EXPECTED_COMMA;
  3853.   fd->Name = in.pos = SkipBlanks(++in.pos);
  3854.   in.pos = SkipBlanks(endptr = SkipName(in.pos));
  3855.   if(*in.pos != '('/*)*/)
  3856.     return ERR_EXPECTED_OPEN_BRACKET;
  3857.   *endptr = 0;
  3858.   in.pos = SkipBlanks(++in.pos);
  3859.   if(*in.pos == /*(*/')')
  3860.     return 0;
  3861.   --in.pos;
  3862.   while(*in.pos != /*(*/')')
  3863.   {
  3864.     ULONG i;
  3865.     in.pos = SkipBlanks(in.pos+1);
  3866.  
  3867.     for(i = 0; i < REG_FP0; i++)
  3868.       if(!strnicmp(RegNames[i], in.pos, 2))
  3869.     break;
  3870.     if(i == REG_FP0)
  3871.     {
  3872.       for(; i < MAXREG; i++)
  3873.         if(!strnicmp(RegNames[i], in.pos, 3))
  3874.       break;
  3875.     }
  3876.  
  3877.     if(i == MAXREG)
  3878.       return ERR_EXPECTED_REGISTER_NAME;
  3879.     else if(i >= REG_FP0 && (Flags & FLAG_NOFPU))
  3880.       return ERR_FLOATARG_NOT_ALLOWED;
  3881.  
  3882.     fd->ArgReg[fd->NumArgs] = i; ++fd->NumArgs;
  3883.  
  3884.     if(fd->NumArgs > MAXREG-2)
  3885.       return ERR_TO_MUCH_ARGUMENTS;
  3886.  
  3887.     in.pos = SkipBlanks(in.pos+(i >= REG_FP0 ? 3 : 2));
  3888.  
  3889.     if(*in.pos != ',' && *in.pos != ')')
  3890.       return ERR_EXPECTED_CLOSE_BRACKET;
  3891.   }
  3892.   in.pos = SkipBlanks(in.pos+1);
  3893.   if(*in.pos != ')')
  3894.     return ERR_EXPECTED_CLOSE_BRACKET;
  3895.   return 0;
  3896. }
  3897.  
  3898. ULONG CreateFDFile(STRPTR file, STRPTR to)
  3899. {
  3900.   struct ShortListRoot pl = {0, 0, sizeof(struct PragList)};
  3901.   ULONG linenum, err = 0, skip;
  3902.  
  3903.   for(linenum = 1; !CTRL_C && in.pos < in.buf + in.size; ++linenum)
  3904.   {
  3905.     in.pos = SkipBlanks(in.pos);
  3906.     if(!strncmp("#pragma", in.pos, 7))
  3907.     {
  3908.       struct FDData fd;
  3909.  
  3910.       skip = 0;
  3911.       memset(&fd, 0, sizeof(struct FDData));
  3912.  
  3913.       in.pos = SkipBlanks(in.pos+7);
  3914.       if(!strncmp("tagcall", in.pos, 7))
  3915.       {
  3916.     fd.Mode = 1;
  3917.     in.pos = SkipBlanks(in.pos+7);
  3918.     if(*in.pos == '(' /*)*/)    /* Storm method */
  3919.       err = GetAmiData(&fd);
  3920.     else                /* SAS method */
  3921.     {
  3922.       fd.Basename = in.pos;
  3923.       in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
  3924.       err = GetLibData(&fd);
  3925.     }
  3926.       }
  3927.       else if(!strncmp("amicall", in.pos, 7))    /* Storm method */
  3928.       {
  3929.     in.pos += 7;
  3930.     err = GetAmiData(&fd);
  3931.       }
  3932.       else if(!strncmp("libcall", in.pos, 7))    /* SAS method */
  3933.       {
  3934.     fd.Basename = SkipBlanks(in.pos+7);
  3935.     in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
  3936.     err = GetLibData(&fd);
  3937.       }
  3938.       else if(!strncmp("flibcall", in.pos, 8))    /* SAS method */
  3939.       {
  3940.     fd.Basename = SkipBlanks(in.pos+8);
  3941.     in.pos = SkipName(fd.Basename); *(in.pos++) = 0;
  3942.     err = GetFlibData(&fd);
  3943.       }
  3944.       else if(!strncmp("syscall", in.pos, 7))    /* SAS method */
  3945.       {
  3946.     fd.Basename = "SysBase";
  3947.     err = GetLibData(&fd);
  3948.       }
  3949.       else
  3950.     skip = 1;
  3951.  
  3952.       if(err)
  3953.     DoError(err, linenum);
  3954.       else if(skip)
  3955.     ;
  3956.       else if((err = AddFDData(&pl, &fd)))
  3957.       {
  3958.     if(err != 100)
  3959.       DoError(err, linenum);
  3960.     return 0;
  3961.       }
  3962.     }
  3963.     while(*(in.pos++))    /* jumps to first char of next line */
  3964.       ;
  3965.   }
  3966.  
  3967.   if(pl.First && !CTRL_C)
  3968.   {
  3969.     struct PragList *p = (struct PragList *) pl.First;
  3970.     if(!p->List.Next)
  3971.     {
  3972.       if(!to)
  3973.       {
  3974.     STRPTR text;
  3975.     ULONG i;
  3976.  
  3977.     if(ShortBaseName)
  3978.     {
  3979.       text = ShortBaseName; i = strlen(text);
  3980.     }
  3981.     else
  3982.     {
  3983.       text = p->Basename; i = strlen(text)-4;
  3984.     }
  3985.  
  3986.     to = DupString(text, i + sizeof(FDFILEEXTENSION) - 1);
  3987.     CopyMem(FDFILEEXTENSION, to+i, sizeof(FDFILEEXTENSION));
  3988.       }
  3989.       if(!(out.file = Open(to, MODE_NEWFILE)))
  3990.         return 0;
  3991.       
  3992.       err = MakeFD(p);
  3993.       CloseDest(to);
  3994.       if(!err)
  3995.         return 0;
  3996.     }
  3997.     else
  3998.     {
  3999.       while(p)
  4000.       {
  4001.     ULONG i;
  4002.     i = strlen(p->Basename) - 4;
  4003.     to = DupString(p->Basename, i + sizeof(FDFILEEXTENSION) - 1);
  4004.     CopyMem(FDFILEEXTENSION, to+i, sizeof(FDFILEEXTENSION));
  4005.     if(!(out.file = Open(to, MODE_NEWFILE)))
  4006.       return 0;
  4007.     i = MakeFD(p);
  4008.     CloseDest(to);
  4009.         if(!i)
  4010.           return 0;
  4011.     p = (struct PragList *) p->List.Next;
  4012.       }
  4013.     }
  4014.   }
  4015.  
  4016.   if(CTRL_C)
  4017.     DoError(ERR_USER_ABORT, 0);
  4018.  
  4019.   return 1;
  4020. }
  4021.  
  4022. STRPTR helptext =
  4023. "FDFILE:  the FD file which should be used\n"
  4024. "SPECIAL: 1 - Aztec compiler (xxx_lib.h,     MODE 2, AMICALL)\n"
  4025. "\t 2 - DICE compiler  (xxx_pragmas.h, MODE 3, LIBCALL)\n"
  4026. "\t 3 - SAS compiler   (xxx_pragmas.h, MODE 3, LIBCALL,LIBTAGS)\n"
  4027. "\t 4 - MAXON compiler (xxx_lib.h,     MODE 1, AMICALL)\n"
  4028. "\t 5 - STORM compiler (xxx_lib.h,     MODE 1, AMITAGS,AMICALL)\n"
  4029. "\t 6 - all compilers [default]\n"
  4030. "\t 7 - all compilers with pragma to inline redirect for GCC\n"
  4031. "\t 8 - pragma to inline redirect for GCC\n"
  4032. "\t10 - stub-functions for C - C text\n"
  4033. "\t11 - stub-functions for C - assembler text\n"
  4034. "\t12 - stub-functions for C - link library\n"
  4035. "\t13 - defines and link library for local library base (register call)\n"
  4036. "\t14 - defines and link library for local library base (stack call)\n"
  4037. "\t15 - stub-functions for Pascal - assembler text\n"
  4038. "\t16 - stub-functions for Pascal - link library\n"
  4039. "\t20 - assembler lvo _lvo.i file\n"
  4040. "\t21 - assembler lvo _lib.i file\n"
  4041. "\t22 - assembler lvo _lvo.i file no XDEF\n"
  4042. "\t23 - assembler lvo _lib.i file no XDEF\n"
  4043. "\t30 - proto file with pragma/..._lib.h call\n"
  4044. "\t31 - proto file with pragma/..._pragmas.h call\n"
  4045. "\t32 - proto file with pragmas/..._lib.h call\n"
  4046. "\t33 - proto file with pragmas/..._pragmas.h call\n"
  4047. "\t34 - proto file with local/..._loc.h call\n"
  4048. "\t35 - proto file for all compilers\n"
  4049. "\t36 - proto file for GNU-C compiler only\n"
  4050. "\t40 - GCC inline file (preprocessor based)\n"
  4051. "\t41 - GCC inline file (old type - inline based)\n"
  4052. "\t42 - GCC inline file (library stubs)\n"
  4053. "\t50 - FD file (source is a pragma file!)\n"
  4054. "MODE:\t SPECIAL 1-8,AMICALL,LIBCALL,AMITAGS,LIBTAGS:\n"
  4055. "\t 1 - _INCLUDE_PRAGMA_..._LIB_H definition method [default]\n"
  4056. "\t 2 - _PRAGMAS_..._LIB_H definition method\n"
  4057. "\t 3 - _PRAGMAS_..._PRAGMAS_H definition method\n"
  4058. "\t 4 - no definition\n"
  4059. "\t SPECIAL 11-14:\n"
  4060. "\t 1 - all functions, normal interface\n"
  4061. "\t 2 - only tag-functions, tagcall interface [default]\n"
  4062. "\t 3 - all functions, normal and tagcall interface\n"
  4063. "TO:\t the destination directory (self creation of filename) or\n"
  4064. "\t the destination file\n"
  4065. "CLIB:    name of the prototypes file in clib directory\n"
  4066. "HEADER:  inserts given file into header of created file (\"\" is scan)\n"
  4067. "The following four need a string as argument. This string is used to set\n"
  4068. "a #if<given string> before the set method.\n"
  4069. "AMICALL: creates amicall pragmas\n"
  4070. "LIBCALL: creates libcall pragmas\n"
  4071. "AMITAGS: creates tagcall pragmas (amicall like method (StormC++))\n"
  4072. "LIBTAGS: creates tagcall pragmas (libcall like method (SAS C))\n"
  4073. "Switches:\n"
  4074. "COMMENT:    copy comments found in FD file\n"
  4075. "EXTERNC:    add a #ifdef __cplusplus ... statement to pragma file\n"
  4076. "FPUONLY:    work only with functions using FPU register arguments\n"
  4077. "NOFPU:      disable usage of FPU register arguments\n"
  4078. "PRIVATE:    includes private declared functions\n"
  4079. "SMALLDATA:  generate small data link libraries or assembler text\n"
  4080. "SORTED:     sort generated files by name and not by bias value\n"
  4081. "STORMFD:    converts FD files of strange StormC++ format\n"
  4082. "USESYSCALL: uses syscall pragma instead of libcall SysBase\n";
  4083.  
  4084. void main(void)
  4085. {
  4086.   ULONG mode = 0, pragmode = PRAGMODE_PRAGLIB, callmode = TAGMODE_TAGS;
  4087.   ULONG spec = 0; /* for default setting I need a ULONG var to get a pointer */
  4088.   UBYTE filename[255];    /* needed for filename */
  4089.   struct Args args;
  4090.   STRPTR clibbuf = 0;
  4091.   ULONG clibsize = 0;
  4092.  
  4093. #ifdef __SASC    /* with __MAXON__ this is done automatic by my StartUp */
  4094.   TestOS;
  4095. #endif
  4096.  
  4097.   memset(&args, 0, sizeof(struct Args)); /* initialize */
  4098.   args.SPECIAL = &spec;
  4099.  
  4100.   if(!(rda = (struct RDArgs *) AllocDosObject(DOS_RDARGS, 0)))
  4101.     End(RETURN_FAIL);
  4102.   rda->RDA_ExtHelp = helptext;
  4103.   if(!ReadArgs(PARAM, (LONG *) &args, rda))
  4104.     End(RETURN_FAIL);
  4105.  
  4106.   VPrintf("SourceFile: %s\n", &args.FDFILE);
  4107.  
  4108.   if(
  4109.   !(in.file = Open(args.FDFILE, MODE_OLDFILE)) ||
  4110.   !(fib = (struct FileInfoBlock *) AllocDosObject(DOS_FIB, 0)) ||
  4111.   !ExamineFH(in.file, fib) ||
  4112.   !(in.buf = in.pos = AllocListMem((in.size = fib->fib_Size)+1)) ||
  4113.   Read(in.file, in.buf, in.size) != in.size ||
  4114.   !(out.buf = out.pos = AllocListMem(out.size)))
  4115.     End(RETURN_FAIL);
  4116.  
  4117.   {
  4118.     STRPTR ptr = FilePart(args.FDFILE);
  4119.     LONG len = strlen(ptr) - sizeof(FDFILEEXTENSION) + 1;
  4120.     if(len >= 0 && !stricmp(ptr+len, FDFILEEXTENSION))
  4121.     {
  4122.       ShortBaseName = ptr;
  4123.       ptr[len] = '\0';
  4124.     }
  4125.   }
  4126.  
  4127.   MakeLines(in.pos, in.size);
  4128.  
  4129.   if(args.TO)
  4130.   {
  4131.     if((lock = Lock(args.TO, SHARED_LOCK)) && Examine(lock, fib) &&
  4132.     fib->fib_DirEntryType > 0)
  4133.     {
  4134.       oldfh = CurrentDir(lock);
  4135.       args.TO = 0;
  4136.     }
  4137.     else if(lock)
  4138.     {
  4139.       UnLock(lock);
  4140.       lock = 0;
  4141.     }
  4142.   }
  4143.  
  4144.   if(args.EXTERNC)    Flags ^= FLAG_EXTERNC;
  4145.   if(args.STORMFD)    Flags ^= FLAG_STORMFD;
  4146.   if(args.COMMENT)    Flags ^= FLAG_DOCOMMENT;
  4147.   if(args.PRIVATE)    Flags ^= FLAG_PRIVATE;
  4148.   if(args.SMALLDATA)    Flags ^= FLAG_SMALLDATA;
  4149.   if(args.USESYSCALL)     Flags ^= FLAG_SYSCALL;
  4150.   if(args.NOFPU)    Flags ^= FLAG_NOFPU;
  4151.   if(args.FPUONLY)    Flags ^= FLAG_FPUONLY;
  4152.  
  4153.   if(*args.SPECIAL == 50)
  4154.   {
  4155.     STRPTR ptr = FilePart(args.FDFILE), ptr2;
  4156.  
  4157.     for(ptr2 = ptr; *ptr2 && *ptr2 != '_' && *ptr2 != '.'; ++ptr2)
  4158.       ;
  4159.     if(ptr2 != ptr)
  4160.     {
  4161.       ShortBaseName = ptr;
  4162.       *ptr2 = '\0';
  4163.     }
  4164.     if(!CreateFDFile(args.FDFILE, args.TO))
  4165.       End(RETURN_FAIL);
  4166.     End(RETURN_OK);
  4167.   }
  4168.  
  4169.   Close(in.file);
  4170.   if((in.file = Open(EXTTYPESFILE, MODE_OLDFILE)))
  4171.   {
  4172.     STRPTR ptr;
  4173.  
  4174.     if(ExamineFH(in.file, fib) && (ptr = AllocListMem(fib->fib_Size)) &&
  4175.     Read(in.file, ptr, fib->fib_Size) == fib->fib_Size)
  4176.     {
  4177.       ULONG i;
  4178.       if((i = ScanTypes(ptr, fib->fib_Size)) > 0)
  4179.         DoError(ERR_WRONG_TYPES_LINE, i);
  4180.       if(i)
  4181.         End(RETURN_FAIL);
  4182.     }
  4183.     else
  4184.       End(RETURN_FAIL);
  4185.  
  4186.     Close(in.file); in.file = 0;
  4187.   }
  4188.  
  4189.   if(args.CLIB)
  4190.   {
  4191.     if(!(in.file = Open(args.CLIB, MODE_OLDFILE)) ||
  4192.     !ExamineFH(in.file, fib) ||
  4193.     !(clibbuf = AllocListMem((clibsize = fib->fib_Size + 1))) ||
  4194.     Read(in.file, clibbuf, fib->fib_Size) != fib->fib_Size)
  4195.       End(RETURN_FAIL);
  4196.     ScanClibFile(clibbuf, clibbuf+fib->fib_Size);
  4197.     Close(in.file); in.file = 0;
  4198.   }
  4199.  
  4200.   if(!ScanFDFile())
  4201.     End(RETURN_FAIL);
  4202.  
  4203.   if(args.SORTED)
  4204.     SortFDList();
  4205.  
  4206.   if(!ShortBaseName)
  4207.   {
  4208.     DoError(ERR_MISSING_SHORTBASENAME, 0); End(RETURN_FAIL);
  4209.   }
  4210.   else if((ShortBaseNameUpper = DupString(ShortBaseName, strlen(ShortBaseName))))
  4211.   {
  4212.     STRPTR a = ShortBaseNameUpper;
  4213.     while((*a = toupper(*a)))    /* Convert to uppercase */
  4214.       a++;
  4215.   }
  4216.   else
  4217.     End(RETURN_FAIL);
  4218.  
  4219.   if(*args.SPECIAL < 10) /* the pragma area is up to 9 */
  4220.   {
  4221.     STRPTR amicall = 0, libcall = 0, amitags = 0, libtags = 0;
  4222.  
  4223.     mode = MODUS_PRAGMA;
  4224.     sprintf(filename, "%s_lib.h", ShortBaseName);
  4225.  
  4226.     if(!args.LIBTAGS && !args.AMITAGS && !args.LIBCALL && !args.AMICALL &&
  4227.     !*args.SPECIAL)
  4228.       *args.SPECIAL = 6; /* default mode */
  4229.  
  4230.     switch(*args.SPECIAL)
  4231.     {
  4232.       case 0: break;
  4233.       case 1: pragmode = PRAGMODE_PRAGSLIB; amicall = ""; break;
  4234.       case 2: sprintf(filename, "%s_pragmas.h", ShortBaseName);
  4235.           pragmode = PRAGMODE_PRAGSPRAGS; libcall = ""; break;
  4236.       case 3: sprintf(filename, "%s_pragmas.h", ShortBaseName);
  4237.           pragmode = PRAGMODE_PRAGSPRAGS; libcall = "";
  4238.           libtags = "def " TEXT_SAS_60; break;
  4239.       case 4: amicall = ""; break;
  4240.       case 5: amicall = amitags = ""; break;
  4241.       case 7: Flags |= FLAG_GNUPRAG; /* no break ! */
  4242.       case 6: amicall = " defined(" TEXT_AZTEC ") || defined("
  4243.     TEXT_MAXON ") || defined(" TEXT_STORM ")";
  4244.     libcall = " defined(" TEXT_DICE ") || defined(" TEXT_SAS ")";
  4245.     libtags = "def " TEXT_SAS_60; amitags ="def " TEXT_STORM; break;
  4246.       case 8: sprintf(filename, "%s_pragmas.h", ShortBaseName);
  4247.               Flags |= FLAG_GNUPRAG; pragmode = PRAGMODE_PRAGSPRAGS; break;
  4248.       default: mode = MODUS_ERROR; break;
  4249.     }
  4250.  
  4251.     if(!args.AMICALL)    args.AMICALL = amicall;
  4252.     if(!args.LIBCALL)    args.LIBCALL = libcall;
  4253.     if(!args.AMITAGS)    args.AMITAGS = amitags;
  4254.     if(!args.LIBTAGS)    args.LIBTAGS = libtags;
  4255.  
  4256.     if(args.MODE && *args.MODE > 0 && *args.MODE < 5)
  4257.       pragmode = *args.MODE;
  4258.   }
  4259.   else if(*args.SPECIAL < 20) /* the misc area is up to 19 */
  4260.   {
  4261.     if(args.MODE && *args.MODE > 0 && *args.MODE < 4)
  4262.       callmode = *args.MODE - 1;
  4263.     switch(*args.SPECIAL)
  4264.     {
  4265.     case 10: mode = MODUS_CSTUB;
  4266.       sprintf(filename, "%s_cstub.h", ShortBaseName); break;
  4267.     case 11: mode = MODUS_STUBTEXT;
  4268.       sprintf(filename, "%s_stub.a", ShortBaseName); break;
  4269.     case 12: mode = MODUS_STUBCODE;
  4270.       sprintf(filename, "%s.lib", ShortBaseName); break;
  4271.     case 13: Flags |= FLAG_LOCALREG; /* no break ! */
  4272.     case 14: mode = MODUS_LOCALDATA;
  4273.       sprintf(filename, "%s_loc.h", ShortBaseName); args.TO = 0; break;
  4274.     case 15: mode = MODUS_STUBTEXT; callmode = TAGMODE_NORMAL;
  4275.       Flags ^= FLAG_PASCAL;
  4276.       sprintf(filename, "%s_stub.a", ShortBaseName); break;
  4277.     case 16: mode = MODUS_STUBCODE; callmode = TAGMODE_NORMAL;
  4278.       Flags ^= FLAG_PASCAL;
  4279.       sprintf(filename, "%s.lib", ShortBaseName); break;
  4280.     default: mode = MODUS_ERROR; break;
  4281.     }
  4282.   }
  4283.   else if(*args.SPECIAL < 30) /* the lvo area is up to 29 */
  4284.   {
  4285.     switch(*args.SPECIAL)
  4286.     {
  4287.     case 20: case 22: mode = MODUS_LVO+*args.SPECIAL-20;
  4288.       sprintf(filename, "%s_lvo.i", ShortBaseName); break;
  4289.     case 21: case 23: mode = MODUS_LVO+*args.SPECIAL-20;
  4290.       sprintf(filename, "%s_lib.i", ShortBaseName); break;
  4291.     default: mode = MODUS_ERROR; break;
  4292.     }
  4293.   }
  4294.   else if(*args.SPECIAL < 40) /* the proto area is up to 39 */
  4295.   {
  4296.     if(*args.SPECIAL < 37)
  4297.     {
  4298.       mode = MODUS_PROTO+*args.SPECIAL-30;
  4299.       sprintf(filename, "%s.h", ShortBaseName);
  4300.     }
  4301.     else
  4302.       mode = MODUS_ERROR;
  4303.   }
  4304.   else if(*args.SPECIAL < 50) /* the inline area is up to 49 */
  4305.   {
  4306.     switch(*args.SPECIAL)
  4307.     {
  4308.     case 40: case 41: case 42: mode = MODUS_INLINE+*args.SPECIAL-40;
  4309.       sprintf(filename, "%s.h", ShortBaseName); break;
  4310.     default: mode = MODUS_ERROR; break;
  4311.     }
  4312.   }
  4313.  
  4314.   if(!mode)
  4315.   {
  4316.     SetIoErr(ERROR_REQUIRED_ARG_MISSING);
  4317.     End(RETURN_FAIL);
  4318.   }
  4319.   else if(mode == MODUS_ERROR)
  4320.   {
  4321.     SetIoErr(ERROR_TOO_MANY_ARGS);
  4322.     End(RETURN_FAIL);
  4323.   }
  4324.  
  4325.   /* These modes need BaseName always. */
  4326.   if(!BaseName && (mode == MODUS_PRAGMA || mode == MODUS_STUBTEXT ||
  4327.   mode == MODUS_STUBCODE))
  4328.   {
  4329.     DoError(ERR_MISSING_BASENAME, 0); End(RETURN_FAIL);
  4330.   }
  4331.  
  4332.   if(!args.TO)
  4333.     args.TO = filename;
  4334.  
  4335.   if(args.HEADER)
  4336.   {
  4337.     if(!*args.HEADER)
  4338.       args.HEADER = args.TO;
  4339.     if(!(in.file = Open(args.HEADER, MODE_OLDFILE)) ||
  4340.     !ExamineFH(in.file, fib) ||
  4341.     !(HEADER = AllocListMem((headersize = fib->fib_Size)+1)) ||
  4342.     Read(in.file, HEADER, headersize) != headersize)
  4343.       End(RETURN_FAIL);
  4344.     if(args.HEADER == args.TO)
  4345.       FindHeader();
  4346.     Close(in.file);
  4347.     in.file = 0;
  4348.   }
  4349.  
  4350.   if(!(out.file = Open(args.TO, MODE_NEWFILE)))
  4351.     End(RETURN_FAIL);
  4352.  
  4353.   SetIoErr(0);
  4354.  
  4355.   /* from here mode is used as return result */
  4356.   if(mode == MODUS_PRAGMA)
  4357.     mode = CreatePragmaFile(args.AMICALL, args.LIBCALL, args.AMITAGS,
  4358.     args.LIBTAGS, pragmode);
  4359.   else if(mode == MODUS_CSTUB)
  4360.     mode = CreateCSTUBSFile();
  4361.   else if(mode == MODUS_LOCALDATA)
  4362.     mode = CreateLocalData(args.TO, callmode, clibbuf, clibsize);
  4363.   else if(mode >= MODUS_INLINE)
  4364.     mode = CreateInline(mode-MODUS_INLINE);
  4365.   else if(mode >= MODUS_PROTO)
  4366.     mode = CreateProtoFile(mode-MODUS_PROTO+1);
  4367.   else if(mode >= MODUS_LVO)
  4368.     mode = CreateLVOFile(mode-MODUS_LVO+1);
  4369.   else if(mode)             /* MODUS_STUBTEXT starts with 1 */
  4370.     mode = CreateAsmStubs(mode, callmode);
  4371.  
  4372.   CloseDest(args.TO);
  4373.  
  4374.   if(CTRL_C)
  4375.     DoError(ERR_USER_ABORT, 0);
  4376.   else if(!mode)
  4377.   {
  4378.     DoError(Output_Error ? ERR_UNKNOWN_ERROR : ERR_WRITING_FILE, 0);
  4379.     End(RETURN_FAIL);
  4380.   }
  4381.  
  4382.   End(RETURN_OK);
  4383. }
  4384.  
  4385. void End(ULONG err)
  4386. {
  4387.   if(err && !(Flags & FLAG_DIDERROR))
  4388.     PrintFault(IoErr(), 0);
  4389.  
  4390.   if(fib)        FreeDosObject(DOS_FIB, fib);
  4391.   if(in.file)        Close(in.file);
  4392.   if(oldfh)        CurrentDir(oldfh);
  4393.   if(lock)        UnLock(lock);
  4394.   if(remember)        FreeListMem();
  4395.   if(rda)
  4396.   {
  4397.     FreeArgs(rda);
  4398.     FreeDosObject(DOS_RDARGS, rda);
  4399.   }
  4400.   exit(err);
  4401. }
  4402.